Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/FeliCa2Money.net/Card.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (show annotations) (download)
Sun Jun 1 03:28:48 2008 UTC (16 years ago) by tmurakam
File size: 7517 byte(s)
add test & bug fix
1 /*
2 * FeliCa2Money
3 *
4 * Copyright (C) 2001-2008 Takuya Murakami
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 using System;
22 using System.Collections.Generic;
23 using System.Text;
24 using FelicaLib;
25
26 namespace FeliCa2Money
27 {
28 // Card クラス
29 public abstract class Card
30 {
31 protected string ident; // 組織名
32 protected int bankId = 0; // 銀行番号
33 protected string branchId = "0"; // 支店番号
34 protected string accountId = ""; // 口座番号
35 protected string cardName; // カード名
36
37 public abstract List<Transaction> ReadCard();
38
39 public string Ident
40 {
41 get { return ident; }
42 }
43
44 public int BankId
45 {
46 get { return bankId; }
47 }
48 public string BranchId
49 {
50 get {
51 if (branchId == "") return "0";
52 return branchId;
53 }
54 }
55 public string CardName
56 {
57 get { return cardName; }
58 }
59
60 public string AccountId
61 {
62 set { accountId = value; }
63 get {
64 if (accountId == "") return "0";
65 return accountId;
66 }
67 }
68
69 // タブ区切りの分解 (SFCPeep用)
70 protected string[] ParseLine(string line)
71 {
72 return line.Split('\t');
73 }
74 }
75
76 // FeliCa カードクラス
77 public abstract class CardWithFelicaLib : Card, IDisposable
78 {
79 protected int systemCode; // システムコード
80 protected int serviceCode; // サービスコード
81 protected int blocksPerTransaction = 1; // 1トランザクションあたりのブロック数
82 protected int maxTransactions = 100; // 最大トランザクション数
83 protected bool needReverse = false; // レコード順序を逆転するかどうか
84 protected bool needCalcValue = false; // 入出金額を残高から計算するかどうか
85
86 //--------------------------------------------------------------------
87 // 以下のメソッドはサブクラスで必要に応じてオーバライドする
88
89 // Transaction 解析
90 public abstract bool analyzeTransaction(Transaction t, byte[] data);
91
92 // 後処理
93 protected virtual void PostProcess(List<Transaction> list) { }
94
95 // Dispose 処理
96 public virtual void Dispose() { }
97
98 // カード ID 取得
99 public virtual bool analyzeCardId(IFelica f)
100 {
101 // デフォルトでは、IDm を用いる。
102 byte[] data = f.IDm();
103 if (data == null)
104 {
105 return false;
106 }
107
108 accountId = binString(data, 0, 8);
109
110 return true;
111 }
112
113 //--------------------------------------------------------------------
114
115 // カード読み込み
116 public sealed override List<Transaction> ReadCard()
117 {
118 List<Transaction> list;
119
120 using (IFelica f = new Felica()) {
121 list = ReadCard(f);
122 }
123
124 return list;
125 }
126
127 public List<Transaction> ReadCard(IFelica f)
128 {
129 List<Transaction> list = new List<Transaction>();
130
131 f.Polling(systemCode);
132
133 if (!analyzeCardId(f)) {
134 throw new Exception(Properties.Resources.CantReadCardNo);
135 }
136
137 for (int i = 0; i < maxTransactions; i++)
138 {
139 byte[] data = new byte[16 * blocksPerTransaction];
140 byte[] block = null;
141
142 for (int j = 0; j < blocksPerTransaction; j++)
143 {
144 block = f.ReadWithoutEncryption(serviceCode, i * blocksPerTransaction + j);
145 if (block == null)
146 {
147 break;
148 }
149
150 block.CopyTo(data, j * 16);
151 }
152 if (block == null)
153 {
154 break;
155 }
156
157 Transaction t = new Transaction();
158
159 // データが全0かどうかチェック
160 int x = 0;
161 foreach (int xx in data)
162 {
163 x |= xx;
164 }
165 if (x == 0)
166 {
167 // データが全0なら無視(空エントリ)
168 t.Invalidate();
169 }
170
171 // トランザクション解析
172 else if (!analyzeTransaction(t, data))
173 {
174 t.Invalidate();
175 }
176 list.Add(t);
177 }
178
179 if (needReverse)
180 {
181 list.Reverse();
182 }
183 if (needCalcValue)
184 {
185 CalcValueFromBalance(list);
186 }
187 PostProcess(list);
188
189 return list;
190 }
191
192 //-------------------------------------------------------------------
193 // ユーティリティ
194
195 // バイナリデータを16進文字列に変換
196 protected string binString(byte[] data, int offset, int len)
197 {
198 string s = "";
199 for (int i = offset; i < offset + len; i++)
200 {
201 s += data[i].ToString("X2");
202 }
203 return s;
204 }
205
206 // 残高から金額を計算する
207 private void CalcValueFromBalance(List<Transaction> list)
208 {
209 int prevBalance = 0;
210
211 foreach (Transaction t in list)
212 {
213 t.value = t.balance - prevBalance;
214 prevBalance = t.balance;
215 }
216 list.RemoveAt(0); // 最古のエントリは捨てる
217 }
218
219 // 複数バイト読み込み (big endian)
220 protected int read2b(byte[] b, int pos)
221 {
222 int ret = b[pos] << 8 | b[pos + 1];
223 return ret;
224 }
225
226 protected int read3b(byte[] b, int pos)
227 {
228 int ret = b[pos] << 16 | b[pos + 1] << 8 | b[pos + 2];
229 return ret;
230 }
231
232 protected int read4b(byte[] b, int pos)
233 {
234 int ret = b[pos] << 24 | b[pos + 1] << 16 | b[pos + 2] << 8 | b[pos + 3];
235 return ret;
236 }
237
238 // little endian
239 protected int read2l(byte[] b, int pos)
240 {
241 int ret = b[pos + 1] << 8 | b[pos];
242 return ret;
243 }
244 }
245 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26