예제 #1
0
 protected internal virtual void readToc()
 {
     toc = new Dictionary <int, int>();
     nextFreeBufferedSectorNumber = 0;
     tocDirty = false;
     try
     {
         tocFile.seek(0);
         long Length = tocFile.Length();
         if (Length >= 4)
         {
             numSectors = tocFile.readInt();
             for (long i = 4; i < Length; i += 8)
             {
                 int sectorNumber         = tocFile.readInt();
                 int bufferedSectorNumber = tocFile.readInt();
                 toc[sectorNumber]            = bufferedSectorNumber;
                 nextFreeBufferedSectorNumber = System.Math.Max(nextFreeBufferedSectorNumber, bufferedSectorNumber + 1);
             }
         }
         else if (sectorDevice != null)
         {
             numSectors = sectorDevice.NumSectors;
         }
     }
     catch (IOException e)
     {
         Console.WriteLine("readToc", e);
     }
 }
예제 #2
0
 public DataInputStream getChunkDataInputStream(int i, int j)
 {
     if (outOfBounds(i, j))
     {
         debugln("READ", i, j, "out of bounds");
         return(null);
     }
     try
     {
         int k = getOffset(i, j);
         if (k == 0)
         {
             return(null);
         }
         int l  = k >> 8;
         int i1 = k & 0xff;
         if (l + i1 > sectorFree.size())
         {
             debugln("READ", i, j, "invalid sector");
             return(null);
         }
         dataFile.seek(l * 4096);
         int j1 = dataFile.readInt();
         if (j1 > 4096 * i1)
         {
             debugln("READ", i, j,
                     (new StringBuilder()).append("invalid length: ").append(j1).append(" > 4096 * ").append(i1).
                     toString());
             return(null);
         }
         byte byte0 = dataFile.readByte();
         if (byte0 == 1)
         {
             var abyte0 = new byte[j1 - 1];
             dataFile.read(abyte0);
             var datainputstream =
                 new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte0)));
             return(datainputstream);
         }
         if (byte0 == 2)
         {
             var abyte1 = new byte[j1 - 1];
             dataFile.read(abyte1);
             var datainputstream1 =
                 new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte1)));
             return(datainputstream1);
         }
         else
         {
             debugln("READ", i, j, (new StringBuilder()).append("unknown version ").append(byte0).toString());
             return(null);
         }
     }
     catch (IOException)
     {
         debugln("READ", i, j, "exception");
     }
     return(null);
 }
예제 #3
0
        /**
         * get the region with a int ip address with memory binary search algorithm
         *
         * @param   ip
         * @
         */
        public DataBlock memorySearch(long ip)
        {
            int blen = IndexBlock.getIndexBlockLength();

            if (dbBinStr == null)
            {
                dbBinStr = new byte[(int)raf.length()];
                raf.seek(0L);
                raf.readFully(dbBinStr, 0, dbBinStr.Length);

                //initialize the global vars
                firstIndexPtr    = Util.getIntLong(dbBinStr, 0);
                lastIndexPtr     = Util.getIntLong(dbBinStr, 4);
                totalIndexBlocks = (int)((lastIndexPtr - firstIndexPtr) / blen) + 1;
            }

            //search the index blocks to define the data
            int  l = 0, h = totalIndexBlocks;
            long sip, eip, dataptr = 0;

            while (l <= h)
            {
                int m = (l + h) >> 1;
                int p = (int)(firstIndexPtr + m * blen);

                sip = Util.getIntLong(dbBinStr, p);
                if (ip < sip)
                {
                    h = m - 1;
                }
                else
                {
                    eip = Util.getIntLong(dbBinStr, p + 4);
                    if (ip > eip)
                    {
                        l = m + 1;
                    }
                    else
                    {
                        dataptr = Util.getIntLong(dbBinStr, p + 8);
                        break;
                    }
                }
            }

            //not matched
            if (dataptr == 0)
            {
                return(null);
            }

            //get the data
            int dataLen = (int)((dataptr >> 24) & 0xFF);
            int dataPtr = (int)((dataptr & 0x00FFFFFF));
            int city_id = (int)Util.getIntLong(dbBinStr, dataPtr);
            //String region = new String(dbBinStr, dataPtr + 4, dataLen - 4, "UTF-8");
            var region = Encoding.UTF8.GetString(dbBinStr, dataPtr + 4, dataLen - 4);

            return(new DataBlock(city_id, region, dataPtr));
        }
예제 #4
0
        public virtual DataInputStream GetChunkDataInputStream(int x, int z)
        {
            if (OutOfBounds(x, z))
            {
                return(null);
            }

            try
            {
                int offset = GetOffset(x, z);
                if (offset == 0)
                {
                    return(null);
                }

                int sectorNumber = offset >> 8;
                int numSectors   = offset & 0xFF;

                if (sectorNumber + numSectors > _sectorFree.Count)
                {
                    return(null);
                }

                _file.seek(sectorNumber * SectorBytes);
                int length = _file.readInt();

                if (length > SectorBytes * numSectors)
                {
                    return(null);
                }

                byte version = _file.readByte();
                if (version == VersionGzip)
                {
                    byte[] data = new byte[length - 1];
                    _file.read(data);
                    return(new DataInputStream(new ByteArrayInputStream(data)));
                }

                if (version != VersionDeflate)
                {
                    return(null);
                }
                {
                    byte[] data = new byte[length - 1];
                    _file.read(data);
                    return(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data))));
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }
예제 #5
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public CSOFileSectorDevice(java.io.RandomAccessFile fileAccess, byte[] header) throws java.io.IOException
        public CSOFileSectorDevice(RandomAccessFile fileAccess, sbyte[] header) : base(fileAccess)
        {
            ByteBuffer byteBuffer = ByteBuffer.wrap(header).order(ByteOrder.LITTLE_ENDIAN);

            /*
             *      u32 'CISO'
             *      u64 image size in bytes (first u32 is highest 32-bit, second u32 is lowest 32-bit)
             *      u32 sector size? (00000800 = 2048 = sector size)
             *      u32 ? (1)
             *      u32[] sector offsets (as many as image size / sector size, I guess)
             */
            long lengthInBytes = (((long)byteBuffer.getInt(4)) << 32) | (byteBuffer.getInt(8) & 0xFFFFFFFFL);
            int  sectorSize    = byteBuffer.getInt(16);

            offsetShift   = byteBuffer.get(21) & 0xFF;
            numSectors    = getNumSectors(lengthInBytes, sectorSize);
            sectorOffsets = new long[numSectors + 1];

            sbyte[] offsetData = new sbyte[(numSectors + 1) * 4];
            fileAccess.seek(24);
            fileAccess.readFully(offsetData);
            ByteBuffer offsetBuffer = ByteBuffer.wrap(offsetData).order(ByteOrder.LITTLE_ENDIAN);

            for (int i = 0; i <= numSectors; i++)
            {
                sectorOffsets[i] = offsetBuffer.getInt(i * 4) & 0xFFFFFFFFL;
                if (i > 0)
                {
                    if ((sectorOffsets[i] & sectorOffsetMask) < (sectorOffsets[i - 1] & sectorOffsetMask))
                    {
                        Console.WriteLine(string.Format("Corrupted CISO - Invalid offset [{0:D}]: 0x{1:X8} < 0x{2:X8}", i, sectorOffsets[i], sectorOffsets[i - 1]));
                    }
                }
            }
        }
예제 #6
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private void init(String umdFilename, bool doIsoBuffering) throws java.io.IOException, java.io.FileNotFoundException
        private void init(string umdFilename, bool doIsoBuffering)
        {
            isPBP = false;
            if (string.ReferenceEquals(umdFilename, null) && doIsoBuffering)
            {
                sectorDevice = null;
            }
            else
            {
                RandomAccessFile fileReader = new RandomAccessFile(umdFilename, "r");

                sbyte[] header = new sbyte[headerLength];
                fileReader.seek(0);
                fileReader.read(header);
                fileReader.seek(0);

                if (header[0] == (sbyte)'C' && header[1] == (sbyte)'I' && header[2] == (sbyte)'S' && header[3] == (sbyte)'O')
                {
                    sectorDevice = new CSOFileSectorDevice(fileReader, header);
                }
                else if (header[0] == 0 && header[1] == (sbyte)'P' && header[2] == (sbyte)'B' && header[3] == (sbyte)'P')
                {
                    sectorDevice = new PBPFileSectorDevice(fileReader);
                    isPBP        = true;
                }
                else
                {
                    sectorDevice = new ISOFileSectorDevice(fileReader);
                }
            }

            if (doIsoBuffering)
            {
                string tmp = Settings.Instance.TmpDirectory;
                sectorDevice = new BufferedFileSectorDevice(new RandomAccessFile(tmp + "umdbuffer.toc", "rw"), new RandomAccessFile(tmp + "umdbuffer.iso", "rw"), sectorDevice);
            }

            numSectors = sectorDevice.NumSectors;

            setBrowser();

            if (browser == null && !hasIsoHeader())
            {
                throw new IOException(string.Format("Unsupported file format or corrupted file '{0}'.", umdFilename));
            }
        }
예제 #7
0
        /**
         * initialize the db file
         *
         * @param	raf
         * @
         */
        private void initDbFile(RandomAccessFile raf)
        {
            //1. zero fill the header part
            raf.seek(0L);
            raf.write(new byte[8]);                             //super block
            raf.write(new byte[dbConfig.getTotalHeaderSize()]); //header block

            headerPool = new LinkedList <HeaderBlock>();
            indexPool  = new LinkedList <IndexBlock>();
        }
예제 #8
0
        public static void Main(string[] args)
        {
            try
            {
                RandomAccessFile inToc  = new RandomAccessFile("tmp/umdbuffer.toc", "r");
                RandomAccessFile inIso  = new RandomAccessFile("tmp/umdbuffer.iso", "r");
                RandomAccessFile outIso = new RandomAccessFile("tmp/umd.iso", "rw");

                int numSectors = inToc.readInt();
                Console.WriteLine(string.Format("numSectors={0:D}", numSectors));
                sbyte[] buffer = new sbyte[sectorLength];
                for (int i = 4; i < inToc.Length(); i += 8)
                {
                    int sectorNumber         = inToc.readInt();
                    int bufferedSectorNumber = inToc.readInt();
                    inIso.seek(bufferedSectorNumber * (long)sectorLength);
                    inIso.readFully(buffer);

                    outIso.seek(sectorNumber * (long)sectorLength);
                    outIso.write(buffer);
                }
                inToc.close();
                inIso.close();
                outIso.close();
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
            }
            catch (IOException e)
            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
            }
        }
예제 #9
0
        public RegionFile(File path)
        {
            _offsets         = new int[SectorInts];
            _chunkTimeStamps = new int[SectorInts];

            _fileName = path;

            _sizeDelta = 0;
            try
            {
                if (path.exists())
                {
                    LastModified = path.lastModified();
                }

                _file = new RandomAccessFile(path, "rw");

                if (_file.length() < SectorBytes)
                {
                    // we need to write the chunk offset table
                    for (int i = 0; i < SectorInts; ++i)
                    {
                        _file.writeInt(0);
                    }

                    // write another sector for the timestamp info
                    for (int i = 0; i < SectorInts; ++i)
                    {
                        _file.writeInt(0);
                    }

                    _sizeDelta += SectorBytes * 2;
                }

                if ((_file.length() & 0xfff) != 0)
                {
                    // the file size is not a multiple of 4KB, grow it
                    for (int i = 0; i < (_file.length() & 0xfff); ++i)
                    {
                        _file.write(0);
                    }
                }

                // set up the available sector map
                int nSectors = (int)_file.length() / SectorBytes;
                _sectorFree = new List <bool>(nSectors);

                for (int i = 0; i < nSectors; ++i)
                {
                    _sectorFree.Add(true);
                }

                _sectorFree[0] = false; // chunk offset table
                _sectorFree[1] = false; // for the last modified info

                _file.seek(0);
                for (int i = 0; i < SectorInts; ++i)
                {
                    int offset = _file.readInt();
                    _offsets[i] = offset;
                    if (offset == 0 || (offset >> 8) + (offset & 0xFF) > _sectorFree.Count)
                    {
                        continue;
                    }
                    for (int sectorNum = 0; sectorNum < (offset & 0xFF); ++sectorNum)
                    {
                        _sectorFree[(offset >> 8) + sectorNum] = false;
                    }
                }

                for (int i = 0; i < SectorInts; i++)
                {
                    int lastModValue = _file.readInt();
                    _chunkTimeStamps[i] = lastModValue;
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.ToString());
            }
        }
예제 #10
0
        public PBPFileSectorDevice(RandomAccessFile fileAccess) : base(fileAccess)
        {
            try
            {
                int magic   = endianSwap32(fileAccess.readInt());
                int version = endianSwap32(fileAccess.readInt());
                offsetParamSFO = endianSwap32(fileAccess.readInt());
                offsetIcon0    = endianSwap32(fileAccess.readInt());
                offsetIcon1    = endianSwap32(fileAccess.readInt());
                offsetPic0     = endianSwap32(fileAccess.readInt());
                offsetPic1     = endianSwap32(fileAccess.readInt());
                offsetSnd0     = endianSwap32(fileAccess.readInt());
                offsetPspData  = endianSwap32(fileAccess.readInt());
                offsetPsarData = endianSwap32(fileAccess.readInt());
                if (magic != 0x50425000)
                {
                    throw new IOException(string.Format("Invalid PBP header 0x{0:X8}", magic));
                }
                if (version != 0x00010000 && version != 0x00000100 && version != 0x00010001)
                {
                    throw new IOException(string.Format("Invalid PBP version 0x{0:X8}", version));
                }
                fileAccess.seek(offsetPsarData);
                sbyte[] header   = new sbyte[256];
                int     readSize = fileAccess.read(header);
                if (readSize != header.Length)
                {
                    int psarDataLength = (int)(fileAccess.Length() - offsetPsarData);
                    if (psarDataLength != 0 && psarDataLength != 16)
                    {
                        throw new IOException(string.Format("Invalid PBP header"));
                    }
                }
                else if (header[0] == (sbyte)'N' && header[1] == (sbyte)'P' && header[2] == (sbyte)'U' && header[3] == (sbyte)'M' && header[4] == (sbyte)'D' && header[5] == (sbyte)'I' && header[6] == (sbyte)'M' && header[7] == (sbyte)'G')
                {
                    CryptoEngine cryptoEngine = new CryptoEngine();
                    amctrl = cryptoEngine.AMCTRLEngine;

                    AMCTRL.BBMac_Ctx    macContext    = new AMCTRL.BBMac_Ctx();
                    AMCTRL.BBCipher_Ctx cipherContext = new AMCTRL.BBCipher_Ctx();

                    // getKey
                    amctrl.hleDrmBBMacInit(macContext, 3);
                    amctrl.hleDrmBBMacUpdate(macContext, header, 0xC0);
                    sbyte[] macKeyC0 = new sbyte[16];
                    Array.Copy(header, 0xC0, macKeyC0, 0, macKeyC0.Length);
                    vkey = amctrl.GetKeyFromBBMac(macContext, macKeyC0);

                    // decrypt NP header
                    sbyte[] cipherData = new sbyte[0x60];
                    Array.Copy(header, 0x40, cipherData, 0, cipherData.Length);
                    Array.Copy(header, 0xA0, hkey, 0, hkey.Length);
                    amctrl.hleDrmBBCipherInit(cipherContext, 1, 2, hkey, vkey);
                    amctrl.hleDrmBBCipherUpdate(cipherContext, cipherData, cipherData.Length);
                    amctrl.hleDrmBBCipherFinal(cipherContext);

                    int lbaStart = Utilities.readUnaligned32(cipherData, 0x14);
                    int lbaEnd   = Utilities.readUnaligned32(cipherData, 0x24);
                    numSectors = lbaEnd + 1;
                    lbaSize    = numSectors - lbaStart;
                    blockLBAs  = Utilities.readUnaligned32(header, 0x0C);
                    blockSize  = blockLBAs * ISectorDevice_Fields.sectorLength;
                    numBlocks  = (lbaSize + blockLBAs - 1) / blockLBAs;

                    blockBuffer = new sbyte[blockSize];
                    tempBuffer  = new sbyte[blockSize];

                    table = new TableInfo[numBlocks];

                    int tableOffset = Utilities.readUnaligned32(cipherData, 0x2C);
                    fileAccess.seek(offsetPsarData + tableOffset);
                    sbyte[] tableBytes = new sbyte[numBlocks * 32];
                    readSize = fileAccess.read(tableBytes);
                    if (readSize != tableBytes.Length)
                    {
                        Console.WriteLine(string.Format("Could not read table with size {0:D} (readSize={1:D})", tableBytes.Length, readSize));
                    }

                    IntBuffer tableInts = ByteBuffer.wrap(tableBytes).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
                    for (int i = 0; i < numBlocks; i++)
                    {
                        int p0 = tableInts.get();
                        int p1 = tableInts.get();
                        int p2 = tableInts.get();
                        int p3 = tableInts.get();
                        int p4 = tableInts.get();
                        int p5 = tableInts.get();
                        int p6 = tableInts.get();
                        int p7 = tableInts.get();
                        int k0 = p0 ^ p1;
                        int k1 = p1 ^ p2;
                        int k2 = p0 ^ p3;
                        int k3 = p2 ^ p3;

                        TableInfo tableInfo = new TableInfo();
                        Array.Copy(tableBytes, i * 32, tableInfo.mac, 0, tableInfo.mac.Length);
                        tableInfo.offset  = p4 ^ k3;
                        tableInfo.size    = p5 ^ k1;
                        tableInfo.flags   = p6 ^ k2;
                        tableInfo.unknown = p7 ^ k0;
                        table[i]          = tableInfo;
                    }

                    currentBlock = -1;
                }
            }
            catch (IOException e)
            {
                Console.WriteLine("Reading PBP", e);
            }
        }
예제 #11
0
        public RegionFile(File file)
        {
            lastModified = 0L;
            fileName     = file;
            debugln((new StringBuilder()).append("REGION LOAD ").append(fileName).toString());
            sizeDelta = 0;
            try
            {
                if (file.exists())
                {
                    lastModified = file.lastModified();
                }
                dataFile = new RandomAccessFile(file, "rw");
                if (dataFile.length() < 4096L)
                {
                    for (int i = 0; i < 1024; i++)
                    {
                        dataFile.writeInt(0);
                    }

                    for (int j = 0; j < 1024; j++)
                    {
                        dataFile.writeInt(0);
                    }

                    sizeDelta += 8192;
                }
                if ((dataFile.length() & 4095L) != 0L)
                {
                    for (int k = 0; k < (dataFile.length() & 4095L); k++)
                    {
                        dataFile.write(0);
                    }
                }
                int l = (int)dataFile.length() / 4096;
                sectorFree = new ArrayList(l);
                for (int i1 = 0; i1 < l; i1++)
                {
                    sectorFree.add(Boolean.valueOf(true));
                }

                sectorFree.set(0, Boolean.valueOf(false));
                sectorFree.set(1, Boolean.valueOf(false));
                dataFile.seek(0L);
                for (int j1 = 0; j1 < 1024; j1++)
                {
                    int l1 = dataFile.readInt();
                    offsets[j1] = l1;
                    if (l1 == 0 || (l1 >> 8) + (l1 & 0xff) > sectorFree.size())
                    {
                        continue;
                    }
                    for (int j2 = 0; j2 < (l1 & 0xff); j2++)
                    {
                        sectorFree.set((l1 >> 8) + j2, Boolean.valueOf(false));
                    }
                }

                for (int k1 = 0; k1 < 1024; k1++)
                {
                    int i2 = dataFile.readInt();
                    chunkTimestamps[k1] = i2;
                }
            }
            catch (IOException ioexception)
            {
                ioexception.printStackTrace();
            }
        }
예제 #12
0
        public static void Main(string[] args)
        {
            File fileToc1 = new File("tmp/umdbuffer1.toc");
            File fileIso1 = new File("tmp/umdbuffer1.iso");
            File fileToc2 = new File("tmp/umdbuffer2.toc");
            File fileIso2 = new File("tmp/umdbuffer2.iso");
            File fileToc  = new File("tmp/umdbuffer.toc");
            File fileIso  = new File("tmp/umdbuffer.iso");

            try
            {
                System.IO.FileStream fosToc  = new System.IO.FileStream(fileToc, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                System.IO.FileStream fosIso  = new System.IO.FileStream(fileIso, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                System.IO.FileStream fisToc1 = new System.IO.FileStream(fileToc1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                System.IO.FileStream fisIso1 = new System.IO.FileStream(fileIso1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                System.IO.FileStream fisToc2 = new System.IO.FileStream(fileToc2, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                DataOutput           toc     = new DataOutputStream(fosToc);
                DataOutput           iso     = new DataOutputStream(fosIso);
                DataInput            toc1    = new DataInputStream(fisToc1);
                DataInput            iso1    = new DataInputStream(fisIso1);
                DataInput            toc2    = new DataInputStream(fisToc2);
                RandomAccessFile     iso2    = new RandomAccessFile(fileIso2, "r");

                int numSectors      = toc1.readInt();
                int numSectorsMerge = toc2.readInt();
                toc.writeInt(System.Math.Max(numSectors, numSectorsMerge));

                Dictionary <int, int> tocHashMap = new Dictionary <int, int>();
                for (int i = 4; i < fileToc1.Length(); i += 8)
                {
                    int sectorNumber         = toc1.readInt();
                    int bufferedSectorNumber = toc1.readInt();
                    tocHashMap[sectorNumber] = bufferedSectorNumber;
                    toc.writeInt(sectorNumber);
                    toc.writeInt(bufferedSectorNumber);
                }

                sbyte[] buffer = new sbyte[sectorLength];
                for (int i = 0; i < fileIso1.Length(); i += buffer.Length)
                {
                    iso1.readFully(buffer);
                    iso.write(buffer);
                }

                int nextFreeBufferedSectorNumber = (int)(fileIso1.Length() / sectorLength);
                for (int i = 4; i < fileToc2.Length(); i += 8)
                {
                    int sectorNumber         = toc2.readInt();
                    int bufferedSectorNumber = toc2.readInt();
                    if (!tocHashMap.ContainsKey(sectorNumber))
                    {
                        iso2.seek(bufferedSectorNumber * (long)sectorLength);
                        iso2.readFully(buffer);
                        iso.write(buffer);

                        toc.writeInt(sectorNumber);
                        toc.writeInt(nextFreeBufferedSectorNumber);
                        tocHashMap[sectorNumber] = nextFreeBufferedSectorNumber;
                        nextFreeBufferedSectorNumber++;
                    }
                }

                fosToc.Close();
                fosIso.Close();
                fisToc1.Close();
                fisIso1.Close();
                fisToc2.Close();
                iso2.close();
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
            }
            catch (IOException e)
            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
            }
        }
예제 #13
0
        /**
         * make the Db file
         *
         * @param	dbFile target output file path
         * @
         */
        public void make(String dbFile)
        {
            //check and load the gloabl region
            if (globalRegionFile != null)
            {
                Console.WriteLine("+-Try to load the global region data ...");
                BufferedReader greader = new BufferedReader(new FileReader(globalRegionFile));
                String         gline   = null;
                while ((gline = greader.readLine()) != null)
                {
                    String[] p = gline.split(",");
                    if (p.Length != 5)
                    {
                        continue;
                    }

                    //push the mapping
                    globalRegionMap.put(p[2], Int32.Parse(p[0]));
                }

                greader.close();
                Console.WriteLine("|--[Ok]");
            }

            //alloc the header size
            BufferedReader   reader = new BufferedReader(new FileReader(this.ipSrcFile));
            RandomAccessFile raf    = new RandomAccessFile(dbFile, "rw");

            //init the db file
            initDbFile(raf);
            Console.WriteLine("+-Db file initialized.");

            //analysis main loop
            Console.WriteLine("+-Try to write the data blocks ... ");
            String line = null;

            while ((line = reader.readLine()) != null)
            {
                line = line.trim();
                if (line.length() == 0)
                {
                    continue;
                }
                if (line.charAt(0) == '#')
                {
                    continue;
                }

                //1. get the start ip
                int sIdx = 0, eIdx = 0;
                if ((eIdx = line.indexOf('|', sIdx + 1)) == -1)
                {
                    continue;
                }
                String startIp = line.substring(sIdx, eIdx);

                //2. get the end ip
                sIdx = eIdx + 1;
                if ((eIdx = line.indexOf('|', sIdx + 1)) == -1)
                {
                    continue;
                }
                String endIp = line.substring(sIdx, eIdx);

                //3. get the region
                sIdx = eIdx + 1;
                String region = line.substring(sIdx);

                Console.WriteLine("+-Try to process item " + line);
                addDataBlock(raf, startIp, endIp, region);
                Console.WriteLine("|--[Ok]");
            }
            Console.WriteLine("|--Data block flushed!");
            Console.WriteLine("|--Data file pointer: " + raf.getFilePointer() + "\n");

            //write the index bytes
            Console.WriteLine("+-Try to write index blocks ... ");

            //record the start block
            IndexBlock  indexBlock = null;
            HeaderBlock hb         = null;

            indexBlock = indexPool.getFirst();
            long indexStartIp = indexBlock.getStartIp(),
                 indexStratPtr = raf.getFilePointer(), indexEndPtr;

            headerPool.add(new HeaderBlock(indexStartIp, (int)(indexStratPtr)));

            int blockLength = IndexBlock.getIndexBlockLength();
            int counter = 0, shotCounter = (dbConfig.getIndexBlockSize() / blockLength) - 1;

            //var indexIt = indexPool.iterator();
            //while (indexIt.hasNext())
            foreach (var indexIt in indexPool.iterator())
            {
                indexBlock = indexIt;
                if (++counter >= shotCounter)
                {
                    hb = new HeaderBlock(
                        indexBlock.getStartIp(),
                        (int)raf.getFilePointer()
                        );

                    headerPool.add(hb);
                    counter = 0;
                }

                //write the buffer
                raf.write(indexBlock.getBytes());
            }

            //record the end block
            if (counter > 0)
            {
                indexBlock = indexPool.getLast();
                hb         = new HeaderBlock(
                    indexBlock.getStartIp(),
                    ((int)raf.getFilePointer()) - IndexBlock.getIndexBlockLength()
                    );

                headerPool.add(hb);
            }

            indexEndPtr = raf.getFilePointer();
            Console.WriteLine("|--[Ok]");

            //write the super blocks
            Console.WriteLine("+-Try to write the super blocks ... ");
            raf.seek(0L);   //reset the file pointer
            byte[] superBuffer = new byte[8];
            Util.writeIntLong(superBuffer, 0, indexStratPtr);
            Util.writeIntLong(superBuffer, 4, indexEndPtr - blockLength);
            raf.write(superBuffer);
            Console.WriteLine("|--[Ok]");

            //write the header blocks
            Console.WriteLine("+-Try to write the header blocks ... ");
            //var headerIt = headerPool.iterator();
            //while (headerIt.hasNext())
            //{
            //    HeaderBlock headerBlock = headerIt.next();
            //    raf.write(headerBlock.getBytes());
            //}
            foreach (var headerBlock in headerPool.iterator())
            {
                raf.write(headerBlock.getBytes());
            }

            //write the copyright and the release timestamp info
            Console.WriteLine("+-Try to write the copyright and release date info ... ");
            raf.seek(raf.length());
            //Calendar cal = Calendar.getInstance();
            //SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String copyright = "Created by lionsoul at " + DateTime.Now.ToString("yyyy/MM/dd"); //dateFormat.format(cal.getTime());
            var    timestamp = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;

            raf.write((Int32)timestamp);   //the unix timestamp
            raf.write(copyright.getBytes());
            Console.WriteLine("|--[Ok]");

            reader.close();
            raf.close();
        }