Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public bool OpenDB()
- {
- ErrorMessage = string.Empty;
- try
- {
- FileInfo fi = new FileInfo(FileName);
- FileSize = fi.Length;
- if ( FileSize < 40)
- {
- ErrorMessage = "Bad SxGeo file";
- return false;
- }
- SxStream = new FileStream(FileName, FileMode.Open, FileAccess.Read,
- FileShare.Read);
- }
- catch (Exception ex)
- {
- ErrorMessage = ex.Message;
- CloseDB();
- return false;
- }
- //проверка сигнатуры ('SxG')
- string sgn = BytesToString(ReadBytes(SxStream, 3));
- if (sgn != "SxG")
- {
- ErrorMessage = "Bad signature";
- CloseDB();
- return false;
- }
- //версия файла
- Header.Version = GetVersion((byte)SxStream.ReadByte());
- //чтение timestamp
- uint tstamp = ReadUInt(SxStream, RevBO);
- Header.Timestamp = UnixTimeToDateTime(tstamp);
- //тип базы
- Header.DBType = (SxGeoType)SxStream.ReadByte();
- //кодировка
- Header.DBEncoding = (SxGeoEncoding)SxStream.ReadByte();
- //чтение всего остального заголовка
- Header.fbIndexLen = (byte)SxStream.ReadByte(); ////элементов в индексе первых байт (b_idx_len/byte)
- Header.mIndexLen = ReadUShort(SxStream,RevBO); //элементов в основном индексе (m_idx_len/ushort)
- Header.Range = ReadUShort(SxStream,RevBO); //Блоков в одном элементе индекса (range/ushort)
- Header.DiapCount = ReadUInt(SxStream,RevBO); //Количество диапазонов (db_items)
- Header.IdLen = (byte)SxStream.ReadByte(); //Размер ID-блока в байтах (1 для стран, 3 для городов) (id_len)
- Header.MaxRegion = ReadUShort(SxStream,RevBO); //Максимальный размер записи региона - до 64 кб (max_region)
- Header.MaxCity = ReadUShort(SxStream, RevBO); // Максимальный размер записи города - до 64 кб (max_city)
- Header.RegionSize = ReadUInt(SxStream,RevBO); //Размер справочника регионов (region_size)
- Header.CitySize = ReadUInt(SxStream,RevBO); //Размер справочника городов (city_size)
- Header.MaxCountry = ReadUShort(SxStream, RevBO); //Максимальный размер записи страны - до 64 кб (max_country)
- Header.CountrySize = ReadUInt(SxStream,RevBO); //Размер справочника стран (country_size)
- Header.PackSize = ReadUShort(SxStream, RevBO); //Размер описания формата упаковки города/региона/страны (pack_size)*/
- //проверка заголовка
- if (!string.IsNullOrEmpty(ErrorMessage))
- {
- CloseDB();
- return false;
- }
- if (Header.fbIndexLen * Header.mIndexLen * Header.Range *
- Header.DiapCount * tstamp * Header.IdLen == 0)
- {
- ErrorMessage = "Wrong file format";
- CloseDB();
- return false;
- }
- //вытаскиваем описание формата упаковки
- if (Header.PackSize != 0)
- {
- byte[] packformat = ReadBytes(SxStream, Header.PackSize);
- Header.PackFormat = BytesToString(packformat);
- //разбираем формат упаковки на составляющие структуры
- string[] pack = Header.PackFormat.Split('\0');
- if (pack.Length > 0) Header.pack_country = pack[0];
- if (pack.Length > 1) Header.pack_region = pack[1];
- if (pack.Length > 2) Header.pack_city = pack[2];
- }
- Header.block_len = 3+(uint)Header.IdLen; //длина 1 блока диапазонов
- //вытаскиваем индекс первых байт
- fb_idx_arr = new uint[Header.fbIndexLen];
- for (int i = 0; i < Header.fbIndexLen;i++)
- {
- fb_idx_arr[i] = ReadUInt(SxStream, RevBO);
- }
- //вытаскиваем основной индекс
- m_idx_arr = new uint[Header.mIndexLen];
- for (int i = 0; i < Header.mIndexLen; i++)
- {
- m_idx_arr[i] = ReadUInt(SxStream, RevBO);
- }
- //читаем базу диапазонов IP,
- //если не установлен режим чтения из файла
- if (DatabaseMode != SxGeoMode.FileMode)
- {
- db_b = new byte[Header.DiapCount * Header.block_len];
- db_b = ReadBytes(SxStream, (int)(Header.DiapCount * Header.block_len));
- }
- //загружаем справочники в память
- if (DatabaseMode == SxGeoMode.MemoryAllMode)
- {
- //регионы
- if (Header.RegionSize > 0)
- {
- regions_db = new byte[Header.RegionSize];
- regions_db = ReadBytes(SxStream, (int)Header.RegionSize);
- }
- //города (справочник стран совмещен со справочником городов)
- if (Header.CitySize > 0)
- {
- cities_db = new byte[Header.CitySize];
- cities_db = ReadBytes(SxStream, (int)Header.CitySize);
- }
- }
- //Начало индекса первых байт
- Header.fb_begin = 40 + (uint)Header.PackSize;
- //начало основного индекса
- Header.midx_begin = Header.fb_begin + (uint)Header.fbIndexLen * 4;
- //начало диапазонов
- Header.db_begin = Header.midx_begin + (uint)Header.mIndexLen * 4;
- //начало справочника регионов
- Header.regions_begin = Header.db_begin + Header.DiapCount *
- Header.block_len;
- //начало справочника стран
- Header.countries_begin = Header.regions_begin + Header.RegionSize;
- //начало справочника городов
- Header.cites_begin = Header.countries_begin + Header.CountrySize;
- IsOpen = true;
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement