mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2025-12-08 19:25:22 +00:00
segments editor RC version
This commit is contained in:
parent
f489d2a39a
commit
8b3a039edc
25
data/ip.test.txt
Normal file
25
data/ip.test.txt
Normal file
@ -0,0 +1,25 @@
|
||||
1.0.0.0|1.0.0.255|澳大利亚|0|0|0|0
|
||||
1.0.1.0|1.0.3.255|中国|0|福建省|福州市|电信
|
||||
1.0.4.0|1.0.7.255|澳大利亚|0|维多利亚|墨尔本|0
|
||||
1.0.8.0|1.0.15.255|中国|0|广东省|广州市|电信
|
||||
1.0.16.0|1.0.31.255|日本|0|0|0|0
|
||||
1.0.32.0|1.0.63.255|中国|0|广东省|广州市|电信
|
||||
1.0.64.0|1.0.79.255|日本|0|广岛县|0|0
|
||||
1.0.80.0|1.0.127.255|日本|0|冈山县|0|0
|
||||
1.0.128.0|1.0.128.255|泰国|0|清莱府|0|TOT
|
||||
1.0.129.0|1.0.132.191|泰国|0|曼谷|曼谷|TOT
|
||||
1.0.132.192|1.0.132.255|泰国|0|Nakhon-Ratchasima|0|TOT
|
||||
1.0.133.0|1.0.133.255|泰国|0|素攀武里府|0|TOT
|
||||
1.0.134.0|1.0.134.255|泰国|0|曼谷|曼谷|TOT
|
||||
1.0.135.0|1.0.135.127|泰国|0|华富里府|0|TOT
|
||||
1.0.135.128|1.0.135.255|泰国|0|素攀武里府|0|TOT
|
||||
1.0.136.0|1.0.136.255|泰国|0|龙仔厝府|0|TOT
|
||||
1.0.137.0|1.0.137.255|泰国|0|大城府|0|TOT
|
||||
1.0.138.0|1.0.143.255|泰国|0|曼谷|曼谷|TOT
|
||||
1.0.144.0|1.0.159.255|泰国|0|春蓬府|0|TOT
|
||||
1.0.160.0|1.0.162.255|泰国|0|洛坤府|0|TOT
|
||||
1.0.163.0|1.0.163.255|泰国|0|春蓬府|0|TOT
|
||||
1.0.164.0|1.0.164.63|泰国|0|0|0|TOT
|
||||
1.0.164.64|1.0.164.127|泰国|0|普吉府|0|TOT
|
||||
1.0.164.128|1.0.170.255|泰国|0|0|0|TOT
|
||||
1.0.171.0|1.0.175.255|泰国|0|攀牙府|0|TOT
|
||||
@ -1,5 +1,5 @@
|
||||
192.168.2.1|192.168.2.20|办公室A内网IP
|
||||
192.168.2.21|192.168.2.30|办公室A内网IP
|
||||
192.168.2.31|192.168.2.60|办公室B内网IP
|
||||
192.168.2.61|192.168.2.91|办公室B内网IP
|
||||
223.255.236.0|223.255.239.255|中国|0|上海|上海市|电信
|
||||
192.168.2.1|192.168.2.20|0|0|0|内网IP|办公室A
|
||||
192.168.2.21|192.168.2.30|0|0|0|内网IP|办公室A
|
||||
192.168.2.31|192.168.2.60|0|0|0|内网IP|办公室B
|
||||
192.168.2.61|192.168.2.91|0|0|0|内网IP|办公室B
|
||||
223.255.236.0|223.255.239.255|中国|0|上海|上海市|电信
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"github.com/lionsoul2014/ip2region/maker/golang/xdb"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -303,6 +304,12 @@ func edit() {
|
||||
return
|
||||
}
|
||||
|
||||
rExp, err := regexp.Compile("\\s+")
|
||||
if err != nil {
|
||||
fmt.Printf("failed to compile regexp: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("init the editor from source @ `%s` ... \n", srcFile)
|
||||
var tStart = time.Now()
|
||||
editor, err := xdb.NewEditor(srcFile)
|
||||
@ -314,11 +321,12 @@ func edit() {
|
||||
fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", editor.SegLen(), time.Since(tStart))
|
||||
var help = func() {
|
||||
fmt.Printf("command list: \n")
|
||||
fmt.Printf(" put [segment] : put the specifield segment\n")
|
||||
fmt.Printf(" put_file [file] : put all the segments from the specified file\n")
|
||||
fmt.Printf(" save : save all the changes to the destination source file\n")
|
||||
fmt.Printf(" exit : exit the program\n")
|
||||
fmt.Printf(" help : print this help menu\n")
|
||||
fmt.Printf(" put [segment] : put the specifield $segment\n")
|
||||
fmt.Printf(" put_file [file] : put all the segments from the specified $file\n")
|
||||
fmt.Printf(" list [offset] [size] : list the first $size segments start from $offset\n")
|
||||
fmt.Printf(" save : save all the changes to the destination source file\n")
|
||||
fmt.Printf(" quit : exit the program\n")
|
||||
fmt.Printf(" help : print this help menu\n")
|
||||
}
|
||||
|
||||
help()
|
||||
@ -341,7 +349,7 @@ func edit() {
|
||||
cmd := strings.TrimSpace(line)
|
||||
if cmd == "help" {
|
||||
help()
|
||||
} else if cmd == "exit" {
|
||||
} else if cmd == "quit" {
|
||||
if editor.NeedSave() {
|
||||
fmt.Printf("there are changes that need to save, type 'quit!' to force quit\n")
|
||||
} else {
|
||||
@ -357,22 +365,45 @@ func edit() {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("all segments saved to %s\n", srcFile)
|
||||
} else if strings.HasPrefix(cmd, "list") {
|
||||
var sErr error
|
||||
off, size, l := 0, 10, len("list")
|
||||
str := strings.TrimSpace(cmd)
|
||||
if len(str) > l {
|
||||
sets := rExp.Split(cmd, 3)
|
||||
switch len(sets) {
|
||||
case 2:
|
||||
_, sErr = fmt.Sscanf(cmd, "%s %d", &str, &off)
|
||||
case 3:
|
||||
_, sErr = fmt.Sscanf(cmd, "%s %d %d", &str, &off, &size)
|
||||
}
|
||||
}
|
||||
|
||||
if sErr != nil {
|
||||
fmt.Printf("failed to parse the offset and size: %s\n", sErr)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("+-slice(%d,%d): \n", off, size)
|
||||
for _, s := range editor.Slice(off, size) {
|
||||
fmt.Printf("%s\n", s)
|
||||
}
|
||||
} else if strings.HasPrefix(cmd, "put ") {
|
||||
seg := cmd[len("put "):]
|
||||
err = editor.Put(seg)
|
||||
seg := strings.TrimSpace(cmd[len("put "):])
|
||||
o, n, err := editor.Put(seg)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to Put(%s): %s\n", seg, err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("Put(%s): Ok\n", seg)
|
||||
fmt.Printf("Put(%s): Ok, with %d deletes and %d additions\n", seg, o, n)
|
||||
} else if strings.HasPrefix(cmd, "put_file ") {
|
||||
file := cmd[len("put_file "):]
|
||||
err = editor.PutFile(file)
|
||||
file := strings.TrimSpace(cmd[len("put_file "):])
|
||||
o, n, err := editor.PutFile(file)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to PutFile(%s): %s\n", file, err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("PutFile(%s): Ok\n", file)
|
||||
fmt.Printf("PutFile(%s): Ok, with %d deletes and %d additions\n", file, o, n)
|
||||
} else if len(cmd) > 0 {
|
||||
help()
|
||||
}
|
||||
|
||||
@ -81,10 +81,36 @@ func (e *Editor) SegLen() int {
|
||||
return e.segments.Len()
|
||||
}
|
||||
|
||||
func (e *Editor) Put(ip string) error {
|
||||
func (e *Editor) Slice(offset int, size int) []*Segment {
|
||||
var index = -1
|
||||
var out []*Segment
|
||||
var next *list.Element
|
||||
for ele := e.segments.Front(); ele != nil; ele = next {
|
||||
next = ele.Next()
|
||||
s, ok := ele.Value.(*Segment)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// offset match
|
||||
index++
|
||||
if index < offset {
|
||||
continue
|
||||
}
|
||||
|
||||
out = append(out, s)
|
||||
if len(out) >= size {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (e *Editor) Put(ip string) (int, int, error) {
|
||||
seg, err := SegmentFrom(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return e.PutSegment(seg)
|
||||
@ -92,16 +118,17 @@ func (e *Editor) Put(ip string) error {
|
||||
|
||||
// PutSegment put the specified segment into the current segment list with
|
||||
// the following position relationships.
|
||||
// 1, fully contained like:
|
||||
// 1, A - fully contained like:
|
||||
// StartIP------seg.StartIP--------seg.EndIP----EndIP
|
||||
// |------------------|
|
||||
// 2, intersect like:
|
||||
// 2, B - intersect like:
|
||||
// StartIP------seg.StartIP------EndIP------|
|
||||
// |---------------------seg.EndIP
|
||||
//
|
||||
func (e *Editor) PutSegment(seg *Segment) error {
|
||||
var tOne *list.Element
|
||||
func (e *Editor) PutSegment(seg *Segment) (int, int, error) {
|
||||
var next *list.Element
|
||||
var eList []*list.Element
|
||||
var found = false
|
||||
for ele := e.segments.Front(); ele != nil; ele = next {
|
||||
next = ele.Next()
|
||||
s, ok := ele.Value.(*Segment)
|
||||
@ -110,50 +137,114 @@ func (e *Editor) PutSegment(seg *Segment) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// find the related segment
|
||||
if seg.StartIP >= s.StartIP && seg.StartIP <= s.EndIP {
|
||||
tOne = ele
|
||||
// found the related segment
|
||||
if seg.StartIP <= s.EndIP && seg.StartIP >= s.StartIP {
|
||||
found = true
|
||||
}
|
||||
|
||||
if found == false {
|
||||
continue
|
||||
}
|
||||
|
||||
eList = append(eList, ele)
|
||||
if seg.EndIP <= s.EndIP {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if tOne == nil {
|
||||
if len(eList) == 0 {
|
||||
// could this even be a case ?
|
||||
// if the loaded segments contains all the segments we have
|
||||
// from 0 to 0xffffffff
|
||||
return fmt.Errorf("failed to find the related segment")
|
||||
return 0, 0, fmt.Errorf("failed to find the related segment")
|
||||
}
|
||||
|
||||
s, ok := tOne.Value.(*Segment)
|
||||
if !ok {
|
||||
return fmt.Errorf("internal error: invalid segment type")
|
||||
// print for debug
|
||||
// for i, s := range eList {
|
||||
// fmt.Printf("ele %d: %s\n", i, s.Value.(*Segment))
|
||||
// }
|
||||
|
||||
// segment split
|
||||
var sList []*Segment
|
||||
var head = eList[0].Value.(*Segment)
|
||||
if seg.StartIP > head.StartIP {
|
||||
sList = append(sList, &Segment{
|
||||
StartIP: head.StartIP,
|
||||
EndIP: seg.StartIP - 1,
|
||||
Region: head.Region,
|
||||
})
|
||||
}
|
||||
|
||||
fmt.Printf("tOne: %s\n", s)
|
||||
// append the new segment
|
||||
sList = append(sList, seg)
|
||||
|
||||
// check and do the tailing segment append
|
||||
if len(sList) > 0 {
|
||||
// check and append the tailing
|
||||
var tail = eList[len(eList)-1].Value.(*Segment)
|
||||
if seg.EndIP < tail.EndIP {
|
||||
sList = append(sList, &Segment{
|
||||
StartIP: seg.EndIP + 1,
|
||||
EndIP: tail.EndIP,
|
||||
Region: tail.Region,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// print for debug
|
||||
// for i, s := range sList {
|
||||
// fmt.Printf("%d: %s\n", i, s)
|
||||
// }
|
||||
|
||||
// delete all the in-range segments and
|
||||
var base *list.Element
|
||||
var oldRows, newRows = len(eList), len(sList)
|
||||
for _, ele := range eList {
|
||||
base = ele.Next()
|
||||
e.segments.Remove(ele)
|
||||
}
|
||||
|
||||
// add all the new segments
|
||||
if base == nil {
|
||||
for _, s := range sList {
|
||||
e.segments.PushBack(s)
|
||||
}
|
||||
} else {
|
||||
for _, s := range sList {
|
||||
e.segments.InsertBefore(s, base)
|
||||
}
|
||||
}
|
||||
|
||||
// open the to save flag
|
||||
e.toSave = true
|
||||
|
||||
return nil
|
||||
return oldRows, newRows, nil
|
||||
}
|
||||
|
||||
func (e *Editor) PutFile(src string) error {
|
||||
func (e *Editor) PutFile(src string) (int, int, error) {
|
||||
handle, err := os.OpenFile(src, os.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
var oldRows, newRows = 0, 0
|
||||
iErr := IterateSegments(handle, func(l string) {
|
||||
// do nothing here
|
||||
}, func(seg *Segment) error {
|
||||
return e.PutSegment(seg)
|
||||
o, n, err := e.PutSegment(seg)
|
||||
if err == nil {
|
||||
oldRows += o
|
||||
newRows += n
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
if iErr != nil {
|
||||
return iErr
|
||||
return oldRows, newRows, iErr
|
||||
}
|
||||
|
||||
_ = handle.Close()
|
||||
return nil
|
||||
return oldRows, newRows, nil
|
||||
}
|
||||
|
||||
func (e *Editor) Save() error {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user