public SFOParser(string filePath)
{
FileAttributes attr = File.GetAttributes(filePath);
//detect whether its a directory or file
if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
throw new Exception("不是正確的SFO檔");
this.filePath = filePath;
BinaryReader bs = new BinaryReader(new FileStream(filePath, FileMode.Open));
byte[] tmpbuffer = bs.ReadBytes(Marshal.SizeOf(typeof(PsfHdr)));
GCHandle handle = GCHandle.Alloc(tmpbuffer, GCHandleType.Pinned);
psfHdr = (PsfHdr)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(PsfHdr));
handle.Free();
if (!Enumerable.SequenceEqual( psfHdr.psf, new char[] {'\0','P', 'S', 'F'})) {
throw new Exception("不是正確的SFO檔");
}
#if DEBUG
Console.WriteLine("{0}個區塊", psfHdr.nsects);
#endif
psfSec = new PsfSec[psfHdr.nsects];
for (int i = 0; i < psfHdr.nsects; i++) {
tmpbuffer = bs.ReadBytes(Marshal.SizeOf(typeof(PsfSec)));
handle = GCHandle.Alloc(tmpbuffer, GCHandleType.Pinned);
psfSec[i] = (PsfSec)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(PsfSec));
handle.Free();
}
pairs = new SFOPair[psfHdr.nsects];
for (int i = 0; i < psfHdr.nsects; i++) {
bs.BaseStream.Position = psfSec[i].label_off + psfHdr.label_ptr;
tmpbuffer = readByteString(bs);
pairs[i] = new SFOPair();
pairs[i].label = encode.GetString(tmpbuffer);
pairs[i].psfsec = psfSec[i];
bs.BaseStream.Position = psfSec[i].data_off + psfHdr.data_ptr;
tmpbuffer = bs.ReadBytes(psfSec[i].datafield_used);
pairs[i].type = psfSec[i].data_type;
switch (psfSec[i].data_type) {
case 0:
pairs[i].value = tmpbuffer;
break;
case 2:
pairs[i].value = encode.GetString(tmpbuffer);
break;
case 4:
pairs[i].value = BitConverter.ToInt32(tmpbuffer, 0);
break;
default:
break;
}
#if DEBUG
Console.WriteLine("Label:{0}, Type:{1:X}, Value:{2}", pairs[i].label, pairs[i].type, pairs[i].value);
#endif
}
bs.Close();
}