ip2location.go
func query(ipaddress string, mode uint32) IP2Locationrecord {
	x := loadmessage(not_supported) // default message
	
	// read metadata
	if !metaok {
		x = loadmessage(missing_file)
		return x
	}
	
	// check IP type and return IP number & index (if exists)
	iptype, ipno, ipindex := checkip(ipaddress)
	
	if iptype == 0 {
		x = loadmessage(invalid_address)
		return x
	}
	
	var colsize uint32
	var baseaddr uint32
	var low uint32
	var high uint32
	var mid uint32
	var rowoffset uint32
	var rowoffset2 uint32
	ipfrom := big.NewInt(0)
	ipto := big.NewInt(0)
	maxip := big.NewInt(0)
	
	if iptype == 4 {
		baseaddr = meta.ipv4databaseaddr
		high = meta.ipv4databasecount
		maxip = max_ipv4_range
		colsize = meta.ipv4columnsize
	} else {
		baseaddr = meta.ipv6databaseaddr
		high = meta.ipv6databasecount
		maxip = max_ipv6_range
		colsize = meta.ipv6columnsize
	}
	
	// reading index
	if ipindex > 0 {
		low = readuint32(ipindex)
		high = readuint32(ipindex + 4)
	}
	
	if ipno.Cmp(maxip)>=0 {
		ipno = ipno.Sub(ipno, big.NewInt(1))
	}
	
	for low <= high {
		mid = ((low + high) >> 1)
		rowoffset = baseaddr + (mid * colsize)
		rowoffset2 = rowoffset + colsize
		
		if iptype == 4 {
			ipfrom = big.NewInt(int64(readuint32(rowoffset)))
			ipto = big.NewInt(int64(readuint32(rowoffset2)))
		} else {
			ipfrom = readuint128(rowoffset)
			ipto = readuint128(rowoffset2)
		}
		
		if ipno.Cmp(ipfrom)>=0 && ipno.Cmp(ipto)<0 {
			if iptype == 6 {
				rowoffset = rowoffset + 12 // coz below is assuming all columns are 4 bytes, so got 12 left to go to make 16 bytes total
			}
			
			if mode&countryshort == 1 && country_enabled {
				x.Country_short = readstr(readuint32(rowoffset + country_position_offset))
			}
			
			if mode&countrylong != 0 && country_enabled {
				x.Country_long = readstr(readuint32(rowoffset + country_position_offset) + 3)
			}
			
			if mode&region != 0 && region_enabled {
				x.Region = readstr(readuint32(rowoffset + region_position_offset))
			}
			
			if mode&city != 0 && city_enabled {
				x.City = readstr(readuint32(rowoffset + city_position_offset))
			}
			
			if mode&isp != 0 && isp_enabled {
				x.Isp = readstr(readuint32(rowoffset + isp_position_offset))
			}
			
			if mode&latitude != 0 && latitude_enabled {
				x.Latitude = readfloat(rowoffset + latitude_position_offset)
			}
			
			if mode&longitude != 0 && longitude_enabled {
				x.Longitude = readfloat(rowoffset + longitude_position_offset)
			}
			
			if mode&domain != 0 && domain_enabled {
				x.Domain = readstr(readuint32(rowoffset + domain_position_offset))
			}
			
			if mode&zipcode != 0 && zipcode_enabled {
				x.Zipcode = readstr(readuint32(rowoffset + zipcode_position_offset))
			}
			
			if mode&timezone != 0 && timezone_enabled {
				x.Timezone = readstr(readuint32(rowoffset + timezone_position_offset))
			}
			
			if mode&netspeed != 0 && netspeed_enabled {
				x.Netspeed = readstr(readuint32(rowoffset + netspeed_position_offset))
			}
			
			if mode&iddcode != 0 && iddcode_enabled {
				x.Iddcode = readstr(readuint32(rowoffset + iddcode_position_offset))
			}
			
			if mode&areacode != 0 && areacode_enabled {
				x.Areacode = readstr(readuint32(rowoffset + areacode_position_offset))
			}
			
			if mode&weatherstationcode != 0 && weatherstationcode_enabled {
				x.Weatherstationcode = readstr(readuint32(rowoffset + weatherstationcode_position_offset))
			}
			
			if mode&weatherstationname != 0 && weatherstationname_enabled {
				x.Weatherstationname = readstr(readuint32(rowoffset + weatherstationname_position_offset))
			}
			
			if mode&mcc != 0 && mcc_enabled {
				x.Mcc = readstr(readuint32(rowoffset + mcc_position_offset))
			}
			
			if mode&mnc != 0 && mnc_enabled {
				x.Mnc = readstr(readuint32(rowoffset + mnc_position_offset))
			}
			
			if mode&mobilebrand != 0 && mobilebrand_enabled {
				x.Mobilebrand = readstr(readuint32(rowoffset + mobilebrand_position_offset))
			}
			
			if mode&elevation != 0 && elevation_enabled {
				f, _ := strconv.ParseFloat(readstr(readuint32(rowoffset + elevation_position_offset)), 32)
				x.Elevation = float32(f)
			}
			
			if mode&usagetype != 0 && usagetype_enabled {
				x.Usagetype = readstr(readuint32(rowoffset + usagetype_position_offset))
			}
			
			return x
		} else {
			if ipno.Cmp(ipfrom)<0 {
				high = mid - 1
			} else {
				low = mid + 1
			}
		}
	}
	return x
}
func query(ipaddress string, mode uint32) IP2Locationrecord {
	x := loadmessage(not_supported) // default message
	
	// read metadata
	if !metaok {
		x = loadmessage(missing_file)
		return x
	}
	
	// check IP type and return IP number & index (if exists)
	iptype, ipno, ipindex := checkip(ipaddress)
	
	if iptype == 0 {
		x = loadmessage(invalid_address)
		return x
	}
	
	var colsize uint32
	var baseaddr uint32
	var low uint32
	var high uint32
	var mid uint32
	var rowoffset uint32
	var rowoffset2 uint32
	ipfrom := big.NewInt(0)
	ipto := big.NewInt(0)
	maxip := big.NewInt(0)
	
	if iptype == 4 {
		baseaddr = meta.ipv4databaseaddr
		high = meta.ipv4databasecount
		maxip = max_ipv4_range
		colsize = meta.ipv4columnsize
	} else {
		baseaddr = meta.ipv6databaseaddr
		high = meta.ipv6databasecount
		maxip = max_ipv6_range
		colsize = meta.ipv6columnsize
	}
	
	// reading index
	if ipindex > 0 {
		low = readuint32(ipindex)
		high = readuint32(ipindex + 4)
	}
	
	if ipno.Cmp(maxip)>=0 {
		ipno = ipno.Sub(ipno, big.NewInt(1))
	}
	
	for low <= high {
		mid = ((low + high) >> 1)
		rowoffset = baseaddr + (mid * colsize)
		rowoffset2 = rowoffset + colsize
		
		if iptype == 4 {
			ipfrom = big.NewInt(int64(readuint32(rowoffset)))
			ipto = big.NewInt(int64(readuint32(rowoffset2)))
		} else {
			ipfrom = readuint128(rowoffset)
			ipto = readuint128(rowoffset2)
		}
		
		if ipno.Cmp(ipfrom)>=0 && ipno.Cmp(ipto)<0 {
			if iptype == 6 {
				rowoffset = rowoffset + 12 // coz below is assuming all columns are 4 bytes, so got 12 left to go to make 16 bytes total
			}
			
			if mode&countryshort == 1 && country_enabled {
				x.Country_short = readstr(readuint32(rowoffset + country_position_offset))
			}
			
			if mode&countrylong != 0 && country_enabled {
				x.Country_long = readstr(readuint32(rowoffset + country_position_offset) + 3)
			}
			
			if mode&region != 0 && region_enabled {
				x.Region = readstr(readuint32(rowoffset + region_position_offset))
			}
			
			if mode&city != 0 && city_enabled {
				x.City = readstr(readuint32(rowoffset + city_position_offset))
			}
			
			if mode&isp != 0 && isp_enabled {
				x.Isp = readstr(readuint32(rowoffset + isp_position_offset))
			}
			
			if mode&latitude != 0 && latitude_enabled {
				x.Latitude = readfloat(rowoffset + latitude_position_offset)
			}
			
			if mode&longitude != 0 && longitude_enabled {
				x.Longitude = readfloat(rowoffset + longitude_position_offset)
			}
			
			if mode&domain != 0 && domain_enabled {
				x.Domain = readstr(readuint32(rowoffset + domain_position_offset))
			}
			
			if mode&zipcode != 0 && zipcode_enabled {
				x.Zipcode = readstr(readuint32(rowoffset + zipcode_position_offset))
			}
			
			if mode&timezone != 0 && timezone_enabled {
				x.Timezone = readstr(readuint32(rowoffset + timezone_position_offset))
			}
			
			if mode&netspeed != 0 && netspeed_enabled {
				x.Netspeed = readstr(readuint32(rowoffset + netspeed_position_offset))
			}
			
			if mode&iddcode != 0 && iddcode_enabled {
				x.Iddcode = readstr(readuint32(rowoffset + iddcode_position_offset))
			}
			
			if mode&areacode != 0 && areacode_enabled {
				x.Areacode = readstr(readuint32(rowoffset + areacode_position_offset))
			}
			
			if mode&weatherstationcode != 0 && weatherstationcode_enabled {
				x.Weatherstationcode = readstr(readuint32(rowoffset + weatherstationcode_position_offset))
			}
			
			if mode&weatherstationname != 0 && weatherstationname_enabled {
				x.Weatherstationname = readstr(readuint32(rowoffset + weatherstationname_position_offset))
			}
			
			if mode&mcc != 0 && mcc_enabled {
				x.Mcc = readstr(readuint32(rowoffset + mcc_position_offset))
			}
			
			if mode&mnc != 0 && mnc_enabled {
				x.Mnc = readstr(readuint32(rowoffset + mnc_position_offset))
			}
			
			if mode&mobilebrand != 0 && mobilebrand_enabled {
				x.Mobilebrand = readstr(readuint32(rowoffset + mobilebrand_position_offset))
			}
			
			if mode&elevation != 0 && elevation_enabled {
				f, _ := strconv.ParseFloat(readstr(readuint32(rowoffset + elevation_position_offset)), 32)
				x.Elevation = float32(f)
			}
			
			if mode&usagetype != 0 && usagetype_enabled {
				x.Usagetype = readstr(readuint32(rowoffset + usagetype_position_offset))
			}
			
			return x
		} else {
			if ipno.Cmp(ipfrom)<0 {
				high = mid - 1
			} else {
				low = mid + 1
			}
		}
	}
	return x
}
// main query