R3D

  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[文件格式]CSF格式

Posted on 2007-12-17 23:44  Yuri.  阅读(959)  评论(0)    收藏  举报
文件头:
struct CsfHeader
{
    
int id;
    
int flag1;
    
int count1;
    
int count2;
    
int zero;
    
int flag2;
}

文件头:
 4个字节:文件类型标记“CSF_(空格)”
 4个字节的flag1,暂时不清楚是做什么的(不过pd貌似知道)
 32位整数(4个字节),表示记录数量
 32位整数(4个字节),另一个数量,暂时不知道是干什么的
 32位整数(4个字节),常数0
 4个字节的flag2,暂时不清楚是做什么的

文件头后边紧接着若干条记录,每个记录的格式:
 一个标记“LBL_(空格)”,4字节
 4个字节的flag
 一个32位整数,表示接下来的记录名称(如:NAME:GACNST)的长度
 若干字节,每个字节代表一个半角字符
 如果(flag & 1)不等于0
  4个字节的flag2,可以是“STR_(空格)”或“STRW”
  一个32位整数,表示接下来的记录内容(如:盟軍建造場)的长度x
  一段长度为2*x的数据,从数据结构上对应一个字符串。逐个字节(无符号sbyte)读出时需要取字节值的相反数并减1,这样才能和一个字符串对应上。
  如果之前的flag2是STRW,那么这个记录会有附加数据
   首先是一个32位整数,表示附加数据(字符串)的长度a
   接下来a个字节,附加数据
 如果(flag & 1)等于0,该项记录内容为空,只有名称,后边不再有这条记录的其它数据

读取文件代码:

unsafe void Read(Stream src)
{
    BinaryReader br 
= new BinaryReader(src);

    CsfHeader header;

    header.id 
= (FileID)br.ReadInt32();
    
if (header.id == FileID.Csf)
    
{
        header.flag1 
= br.ReadInt32();
        header.count1 
= br.ReadInt32();
        header.count2 
= br.ReadInt32();
        header.zero 
= br.ReadInt32();
        header.flag2 
= br.ReadInt32();

        data 
= new Dictionary<string, KeyValuePair<stringstring>>(header.count1);

        
for (int i = 0; i < header.count1; i++)
        
{
            
int id = br.ReadInt32();

            
if (id == CsfHeader.LabelID)
            
{
                
int flag = br.ReadInt32();

                
int len = br.ReadInt32();
                
char[] chs = br.ReadChars(len);
                
string key = new string(chs).ToUpper();

                
if ((flag & 1!= 0)
                
{
                    id 
= br.ReadInt32(); // label内容类型

                    
// 读字符串(内容)
                    len = br.ReadInt32(); //长度

                    
sbyte[] value = new sbyte[len * 2];

                    
for (int j = 0; j < value.Length; j++)
                        value[j] 
= (sbyte)(-br.ReadSByte() - 1);

                    GCHandle h 
= GCHandle.Alloc(value, GCHandleType.Pinned);
                    
string val = new string((char*)h.AddrOfPinnedObject().ToPointer());
                    h.Free();

                    
string ext = null;
                    
// 读附加数据
                    if (id == CsfHeader.WStringID)
                    
{
                        len 
= br.ReadInt32();
                        ext 
= new string(br.ReadChars(len));
                    }


                    data.Add(key, 
new KeyValuePair<stringstring>(ext, val));
                }

                
else
                    data.Add(key, 
new KeyValuePair<stringstring>(""""));
            }

        }

    }

    
else
        
throw new FormatException(src.ToString());

    br.Close();
}