为了编程方便。将NPK文件流分为四个部分。
NPK文件解析的时候将流分割成四个部分存入对应的缓冲区;NPK文件修改时对四个部分直接进行物理修改;保存的时候只需要重新串起来就可以了。
因此一个NPK对象可以这么定义:逻辑值包括目录(即IMG索引)、IMG个数;物理值包括四个数据流。
四个流命名为data1, data2, data3, data4,在对NPK进行读取时不可变,对NPK进行修改时可变,用途如下:
data1:包含NPK头的NeoplePack_Bill字符串以及包含img的个数。定长20字节。
data2:IMG目录,包含IMG的所有索引项。长度为264字节×项数(即data1里img的个数)。
data3:NPK校验位,为data1和data2加起来后前17字节的整数倍的SHA256校验码。定长32字节。
data4:IMG文件数据首尾相接构成的大数据流,占NPK文件的绝大部分。
修改NPK时一般的步骤如下:
1. 先修改逻辑值,即IMG个数以及目录:
若涉及IMG插入与删除操作,则IMG个数相应地增加或减少;
当IMG发生修改或者添加或减少的时候,先将输入IMG索引项的三个参数(偏移量、大小、名字)确定,然后根据内部内容的变化,调整所有索引项内的偏移量。
2. 修改完逻辑值后,根据逻辑值调整物理值:
对data1,若IMG个数变化,则需要重写(或者只修改最后4字节);
对data2,重写(基本都要重写);
对data3,根据data1、data2重新计算校验码;
对data4,需要在计算变动目录项的偏移量时进行记录,然后根据该记录值来进行流的增删。
下面列出几个基本操作的处理流程。
1. 增加IMG(PUSH)
输入:IMG对象(IMG文件流),IMG名字
处理方式:
a. 先生成一个索引项:偏移量 = NPK大小,大小 = IMG文件流大小,名字 = IMG名字;
b. 在目录后插入这个索引项;
c. 因为目录中增加了一个索引项,目录内的索引项的偏移量都增加264个字节(等于一个IMG索引项的大小);
d. IMG数加1;
e. 重新计算data1、data2、data3;
f. data4文件后直接插入IMG文件流。
2. 插入IMG(INSERT)
输入:插入位置pos(若插入位置为最后,则演变为PUSH,但PUSH不是INSERT的特例),IMG对象,IMG名字
处理方式:
a. 先生成一个索引项:偏移量 = 目录在pos处索引项的偏移量,大小 = IMG文件流大小,名字 = IMG名字;
b. 将这个索引项的偏移量记录下来,减去当前的data1、data2、data3的总长度之和,得到data4插入数据在data4内部的偏移量,记录下来;
b. 在目录的pos处插入这个索引项;
c. 因为目录中增加了一个索引项,目录内的索引项的偏移量都增加264个字节;
d. 目录中pos处之后的索引项,偏移量增加IMG文件流的大小个字节;
e. IMG数加1;
f. 重新计算data1、data2、data3;
g. data4文件中,在b步骤所记录下的偏移量处,插入IMG文件流。
3.删除IMG(DELETE)
输入:删除位置pos
处理方式:
a. 生成一个索引项从目录的pos处提取出来即可,其:偏移量 = 目录在pos处索引项的偏移量,大小 = 目录在pos处索引项的大小,名字不用管;
b. 记录该索引项的偏移量,减去当前的data1、data2、data3的总长度之和,得到data4待删除数据在data4内部的偏移量,记录下来;
c. 在目录处的pos处删除这个索引项;
d. 因为在目录中删除了一个索引项,目录内所有索引项的偏移量都减少264个字节;
e. 目录中pos处和pos处之后的索引项,偏移量减少a步骤中索引项的大小个字节;(注:由于pos处原索引项已删除,所以当前pos处实质上是原pos+1处索引项)
f. IMG数减1;
g. 重新计算data1、data2、data3;
h. data4文件中,在b步骤所记录下的偏移量处,删除等于a步骤中索引项的大小个字节。
4.替换IMG(REPLACE)
输入:替换位置pos、替换后的IMG对象
处理方式:
a. 生成一个索引项:从目录的pos处提取出来即可,其:偏移量 = 目录在pos处索引项的偏移量,大小 = 目录在pos处索引项的大小,名字不用管;
b. 记录该索引项的偏移量,减去当前的data1、data2、data3的总长度之和,得到data4待替换数据在data4内部的偏移量,记录下来;
c. 在目录的pos处找到这个索引项,把大小变成IMG文件流的大小,其他不变;
e. 目录中pos出之后的索引项,偏移量减少原索引项(步骤a提取出的索引项)的大小再增加IMG文件流的大小;
f. 重新计算data2、data3;
g. data4文件中,在c步骤所记录的偏移量处,先删除等于原索引项的大小个字节,再插入IMG文件流即可。
5.重命名(RENAME)
输入:重命名位置pos、命名后的字符串
处理方式:
a. 将目录中pos处索引项的名字变为命名后的字符串;
b.重新计算data2、data3。
以上