Compare commits
No commits in common. "master" and "v1.0.0" have entirely different histories.
69
archive.go
69
archive.go
@ -1,69 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unzip 读取位于src的zip文件,并解压到dst文件夹中
|
|
||||||
// shell传入当前解压的文件名称
|
|
||||||
func Unzip(src, dst string, shell func(string)) error {
|
|
||||||
dst, err := filepath.Abs(dst)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !IsFile(src) {
|
|
||||||
return errors.New(src + " Not Exists")
|
|
||||||
}
|
|
||||||
if Exists(dst) && !IsFolder(dst) {
|
|
||||||
return errors.New(dst + " Exists And Not A Folder")
|
|
||||||
}
|
|
||||||
if !Exists(dst) {
|
|
||||||
err := os.MkdirAll(dst, 0755)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zipreader, err := zip.OpenReader(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer zipreader.Close()
|
|
||||||
for _, v := range zipreader.File {
|
|
||||||
name := strings.ReplaceAll(v.Name, "\\", string(os.PathSeparator))
|
|
||||||
if v.FileInfo().IsDir() {
|
|
||||||
err := os.MkdirAll(dst+string(os.PathSeparator)+name, 0755)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fp, err := v.Open()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
go shell(name)
|
|
||||||
dir := filepath.Dir(dst + string(os.PathSeparator) + name)
|
|
||||||
if !Exists(dir) {
|
|
||||||
os.MkdirAll(dir, 0755)
|
|
||||||
}
|
|
||||||
fpdst, err := os.Create(dst + string(os.PathSeparator) + name)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_, err = io.Copy(fpdst, fp)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
fp.Close()
|
|
||||||
fpdst.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Unzip(t *testing.T) {
|
|
||||||
Unzip(`C:\Users\Starainrt\Desktop\o\BK.ZIP`, `C:\Users\Starainrt\Desktop\o\lalala`, func(i string) { fmt.Println(i) })
|
|
||||||
}
|
|
536
crypto.go.old
536
crypto.go.old
@ -1,536 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"crypto/rc4"
|
|
||||||
"crypto/sha1"
|
|
||||||
"crypto/sha256"
|
|
||||||
"crypto/sha512"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"hash/crc32"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StarCrypto struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this StarCrypto) SmallEncodeFileByBase64(filepath, outputname string, buffer int) bool {
|
|
||||||
if !Exists(filepath) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rempar := regexp.MustCompile(`(.*)\*(.*)`)
|
|
||||||
if !rempar.Match([]byte(outputname)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rest := rempar.FindSubmatch([]byte(outputname))
|
|
||||||
par1 := string(rest[1])
|
|
||||||
par2 := string(rest[2])
|
|
||||||
bfile, _ := ioutil.ReadFile(filepath)
|
|
||||||
bitlen := len(bfile)
|
|
||||||
i := 1
|
|
||||||
var seed int = buffer
|
|
||||||
if bitlen > seed {
|
|
||||||
for bitlen > seed {
|
|
||||||
coder := base64.StdEncoding.EncodeToString(bfile[seed*(i-1) : seed*i])
|
|
||||||
ioutil.WriteFile(par1+strconv.Itoa(i)+par2, []byte(coder), 0755)
|
|
||||||
i++
|
|
||||||
bitlen -= seed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
coder := base64.StdEncoding.EncodeToString(bfile[seed*(i-1):])
|
|
||||||
ioutil.WriteFile(par1+strconv.Itoa(i)+par2, []byte(coder), 0755)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this StarCrypto) SmallDecodeFileByBase64(inputname, outputname string, filesum int) bool {
|
|
||||||
rempar := regexp.MustCompile(`(.*)\*(.*)`)
|
|
||||||
if !rempar.Match([]byte(inputname)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rest := rempar.FindSubmatch([]byte(inputname))
|
|
||||||
par1 := string(rest[1])
|
|
||||||
par2 := string(rest[2])
|
|
||||||
for i := 1; i <= filesum; i++ {
|
|
||||||
if !Exists(par1 + strconv.Itoa(i) + par2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i := 1
|
|
||||||
big := filesum
|
|
||||||
res := []byte{}
|
|
||||||
for i <= big {
|
|
||||||
bfile, _ := ioutil.ReadFile(par1 + strconv.Itoa(i) + par2)
|
|
||||||
coder, _ := base64.StdEncoding.DecodeString(string(bfile))
|
|
||||||
for _, v := range coder {
|
|
||||||
res = append(res, v)
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
//time.Sleep(time.Microsecond * 560)
|
|
||||||
}
|
|
||||||
ioutil.WriteFile(outputname, res, 0755)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
需要改写
|
|
||||||
*/
|
|
||||||
func (this StarCrypto) EncodeFileByBase64(filepath, outputname string, buffer int) bool {
|
|
||||||
if !Exists(filepath) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rempar := regexp.MustCompile(`(.*)\*(.*)`)
|
|
||||||
if !rempar.Match([]byte(outputname)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rest := rempar.FindSubmatch([]byte(outputname))
|
|
||||||
par1 := string(rest[1])
|
|
||||||
par2 := string(rest[2])
|
|
||||||
ret := this.SlitFile(filepath, outputname, 0, int64(buffer), int64(buffer)/10)
|
|
||||||
if !ret {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
i := 1
|
|
||||||
for {
|
|
||||||
if !Exists(par1 + strconv.Itoa(i) + par2) {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
bfile, _ := ioutil.ReadFile(par1 + strconv.Itoa(i) + par2)
|
|
||||||
coder := base64.StdEncoding.EncodeToString(bfile)
|
|
||||||
ioutil.WriteFile(par1+strconv.Itoa(i)+par2, []byte(coder), 0755)
|
|
||||||
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this StarCrypto) DecodeFileByBase64(inputname, outputname string, filesum int) bool {
|
|
||||||
rempar := regexp.MustCompile(`(.*)\*(.*)`)
|
|
||||||
if !rempar.Match([]byte(inputname)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rest := rempar.FindSubmatch([]byte(inputname))
|
|
||||||
par1 := string(rest[1])
|
|
||||||
par2 := string(rest[2])
|
|
||||||
if filesum != 0 {
|
|
||||||
for i := 1; i <= filesum; i++ {
|
|
||||||
if !Exists(par1 + strconv.Itoa(i) + par2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var i int
|
|
||||||
for i = 1; ; i++ {
|
|
||||||
if !Exists(par1 + strconv.Itoa(i) + par2) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filesum = i - 1
|
|
||||||
}
|
|
||||||
i := 1
|
|
||||||
big := filesum
|
|
||||||
fpw, _ := os.Create(outputname)
|
|
||||||
defer fpw.Close()
|
|
||||||
for i <= big {
|
|
||||||
bfile, _ := ioutil.ReadFile(par1 + strconv.Itoa(i) + par2)
|
|
||||||
coder, _ := base64.StdEncoding.DecodeString(string(bfile))
|
|
||||||
fpw.Write(coder)
|
|
||||||
i++
|
|
||||||
//time.Sleep(time.Microsecond * 560)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this StarCrypto) SlitFile(filename, outputname string, num int, databig, buffer int64) bool {
|
|
||||||
rempar := regexp.MustCompile(`(.*)\*(.*)`)
|
|
||||||
if !rempar.Match([]byte(outputname)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rest := rempar.FindSubmatch([]byte(outputname))
|
|
||||||
par1 := string(rest[1])
|
|
||||||
par2 := string(rest[2])
|
|
||||||
if !Exists(filename) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fileinfo, _ := os.Stat(filename)
|
|
||||||
filesize := fileinfo.Size()
|
|
||||||
var spbyte int64
|
|
||||||
if num != 0 {
|
|
||||||
spbyte = filesize / int64(num)
|
|
||||||
}
|
|
||||||
if databig != 0 {
|
|
||||||
spbyte = databig
|
|
||||||
num = int(filesize/spbyte + 1)
|
|
||||||
}
|
|
||||||
if buffer == 0 {
|
|
||||||
buffer = spbyte / 10
|
|
||||||
}
|
|
||||||
if buffer > 100*1024*1024 {
|
|
||||||
buffer = 50 * 1024 * 1024
|
|
||||||
}
|
|
||||||
fp, _ := os.Open(filename)
|
|
||||||
defer fp.Close()
|
|
||||||
data := make([]byte, buffer)
|
|
||||||
var i int64 = 0
|
|
||||||
var k int = 1
|
|
||||||
fpw, _ := os.Create(par1 + strconv.Itoa(k) + par2)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i += int64(n)
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
if i > spbyte && k < num {
|
|
||||||
fpw.Close()
|
|
||||||
k++
|
|
||||||
i = 1
|
|
||||||
fpw, _ = os.Create(par1 + strconv.Itoa(k) + par2)
|
|
||||||
defer fpw.Close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func SpliceFile(inputname, outputname string, num int, buffer int64) bool {
|
|
||||||
rempar := regexp.MustCompile(`(.*)\*(.*)`)
|
|
||||||
if !rempar.Match([]byte(inputname)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
rest := rempar.FindSubmatch([]byte(inputname))
|
|
||||||
par1 := string(rest[1])
|
|
||||||
par2 := string(rest[2])
|
|
||||||
if num != 0 {
|
|
||||||
for i := 1; i <= num; i++ {
|
|
||||||
if !Exists(par1 + strconv.Itoa(i) + par2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var i int
|
|
||||||
for i = 1; ; i++ {
|
|
||||||
if !Exists(par1 + strconv.Itoa(i) + par2) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num = i - 1
|
|
||||||
}
|
|
||||||
fpw, _ := os.Create(outputname)
|
|
||||||
defer fpw.Close()
|
|
||||||
fileinfo, _ := os.Stat(par1 + "1" + par2)
|
|
||||||
filesize := fileinfo.Size()
|
|
||||||
if buffer == 0 {
|
|
||||||
buffer = filesize / 5
|
|
||||||
}
|
|
||||||
if buffer > 1024*1024*100 {
|
|
||||||
buffer = 1024 * 1024 * 100
|
|
||||||
}
|
|
||||||
data := make([]byte, buffer)
|
|
||||||
for i := 1; i <= num; i++ {
|
|
||||||
fp, _ := os.Open(par1 + strconv.Itoa(i) + par2)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
}
|
|
||||||
fp.Close()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this StarCrypto) MixFile(filepath, outputname string, buffer int64, remix bool) bool {
|
|
||||||
if !Exists(filepath) || !IsFile(filepath) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fileinfo, _ := os.Stat(filepath)
|
|
||||||
filesize := fileinfo.Size()
|
|
||||||
if buffer == 0 {
|
|
||||||
buffer = filesize / 5
|
|
||||||
}
|
|
||||||
if buffer > 1024*1024*100 {
|
|
||||||
buffer = 1024 * 1024 * 100
|
|
||||||
}
|
|
||||||
var spbyte int64
|
|
||||||
if !remix {
|
|
||||||
spbyte = filesize / 2
|
|
||||||
} else {
|
|
||||||
spbyte = filesize - filesize/2
|
|
||||||
}
|
|
||||||
fpw, _ := os.Create(outputname)
|
|
||||||
defer fpw.Close()
|
|
||||||
fp, _ := os.Open(filepath)
|
|
||||||
defer fp.Close()
|
|
||||||
data := make([]byte, buffer)
|
|
||||||
_, _ = fp.Seek(spbyte, 0)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
}
|
|
||||||
_, _ = fp.Seek(0, 0)
|
|
||||||
i := int64(0)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i += int64(n)
|
|
||||||
if i < spbyte {
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
} else {
|
|
||||||
data = data[:(int64(n) - i + spbyte)]
|
|
||||||
fpw.Write(data)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func Md5File(filepath string) string {
|
|
||||||
f, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Open", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
md5hash := md5.New()
|
|
||||||
if _, err := io.Copy(md5hash, f); err != nil {
|
|
||||||
fmt.Println("Copy", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := md5hash.Sum(nil)
|
|
||||||
return hex.EncodeToString(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Crc32File(filepath string) string {
|
|
||||||
f, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Open", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
defer f.Close()
|
|
||||||
crchash := crc32.NewIEEE()
|
|
||||||
if _, err := io.Copy(crchash, f); err != nil {
|
|
||||||
fmt.Println("Copy", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := crchash.Sum(nil)
|
|
||||||
return hex.EncodeToString(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha1File(filepath string) string {
|
|
||||||
f, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Open", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
defer f.Close()
|
|
||||||
sha1hash := sha1.New()
|
|
||||||
if _, err := io.Copy(sha1hash, f); err != nil {
|
|
||||||
fmt.Println("Copy", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := sha1hash.Sum(nil)
|
|
||||||
return hex.EncodeToString(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha256File(filepath string) string {
|
|
||||||
f, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Open", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
defer f.Close()
|
|
||||||
sha256hash := sha256.New()
|
|
||||||
if _, err := io.Copy(sha256hash, f); err != nil {
|
|
||||||
fmt.Println("Copy", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := sha256hash.Sum(nil)
|
|
||||||
return hex.EncodeToString(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Sha512File(filepath string) string {
|
|
||||||
f, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Open", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
defer f.Close()
|
|
||||||
sha512hash := sha512.New()
|
|
||||||
if _, err := io.Copy(sha512hash, f); err != nil {
|
|
||||||
fmt.Println("Copy", err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := sha512hash.Sum(nil)
|
|
||||||
return hex.EncodeToString(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RC4File(filepath string, key []byte) string {
|
|
||||||
rc4obj, _ := rc4.NewCipher(key)
|
|
||||||
plain, _ := ioutil.ReadFile(filepath)
|
|
||||||
res := make([]byte, len(plain))
|
|
||||||
rc4obj.XORKeyStream(res, plain)
|
|
||||||
return hex.EncodeToString(res)
|
|
||||||
}
|
|
||||||
func DetachFile(source, output1, output2 string, key int64) bool {
|
|
||||||
if !Exists(source) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fin, _ := os.Stat(source)
|
|
||||||
filesize := fin.Size()
|
|
||||||
fpw, _ := os.Create(output1)
|
|
||||||
fp, _ := os.Open(source)
|
|
||||||
defer fp.Close()
|
|
||||||
buffer := filesize / 10
|
|
||||||
if buffer > 100*1024*1024 {
|
|
||||||
buffer = 100 * 1024 * 1024
|
|
||||||
}
|
|
||||||
data := make([]byte, buffer)
|
|
||||||
i := int64(0)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i += int64(n)
|
|
||||||
if i < key {
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
} else {
|
|
||||||
data = data[:(int64(n) - i + key)]
|
|
||||||
fpw.Write(data)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fpw.Close()
|
|
||||||
_, _ = fp.Seek(key+20, 0)
|
|
||||||
fpw, _ = os.Create(output2)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
func AttachFile(source, target, output string) (bool, string) {
|
|
||||||
if !Exists(source) {
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
if !Exists(target) {
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
fin, _ := os.Stat(source)
|
|
||||||
filesize := fin.Size()
|
|
||||||
_ = ioutil.WriteFile(output+".ini", []byte(strconv.FormatInt(filesize, 10)), 0755)
|
|
||||||
fpw, _ := os.Create(output)
|
|
||||||
defer fpw.Close()
|
|
||||||
fp, _ := os.Open(source)
|
|
||||||
buffer := filesize / 10
|
|
||||||
if buffer > 100*1024*1024 {
|
|
||||||
buffer = 100 * 1024 * 1024
|
|
||||||
}
|
|
||||||
data := make([]byte, buffer)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
}
|
|
||||||
fp.Close()
|
|
||||||
fpw.Write([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
|
|
||||||
fin, _ = os.Stat(target)
|
|
||||||
filesize2 := fin.Size()
|
|
||||||
fp, _ = os.Open(target)
|
|
||||||
buffer = filesize2 / 10
|
|
||||||
if buffer > 100*1024*1024 {
|
|
||||||
buffer = 100 * 1024 * 1024
|
|
||||||
}
|
|
||||||
data = make([]byte, buffer)
|
|
||||||
for {
|
|
||||||
data = data[:cap(data)]
|
|
||||||
// read bytes to slice
|
|
||||||
n, err := fp.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
data = data[:n]
|
|
||||||
fpw.Write(data)
|
|
||||||
}
|
|
||||||
fp.Close()
|
|
||||||
return true, strconv.FormatInt(filesize, 10)
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_FileSumAll(t *testing.T) {
|
|
||||||
cry := new(StarCrypto)
|
|
||||||
fmt.Println(cry.FileSumAll("D:\\Download\\macos.iso",[]string{"md5"}, func(pect float64) {
|
|
||||||
fmt.Printf("已处理%f\r", pect)
|
|
||||||
}))
|
|
||||||
}
|
|
833
database.go
833
database.go
@ -3,835 +3,9 @@ package starainrt
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DBRes 单连接下的数据库资源句柄
|
|
||||||
var DBRes *sql.DB
|
|
||||||
|
|
||||||
// DBRows 单连接下的数据库查询句柄
|
|
||||||
var DBRows *sql.Rows
|
|
||||||
|
|
||||||
// StarDB 一个简单封装的DB库
|
|
||||||
type StarDB struct {
|
|
||||||
DB *sql.DB
|
|
||||||
Rows *sql.Rows
|
|
||||||
}
|
|
||||||
|
|
||||||
// StarRows 为查询结果集(按行)
|
|
||||||
type StarRows struct {
|
|
||||||
Rows *sql.Rows
|
|
||||||
Length int
|
|
||||||
StringResult []map[string]string
|
|
||||||
Columns []string
|
|
||||||
ColumnsType []reflect.Type
|
|
||||||
columnref map[string]int
|
|
||||||
result [][]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StarResult 为查询结果集(总)
|
|
||||||
type StarResult struct {
|
|
||||||
Result []interface{}
|
|
||||||
Columns []string
|
|
||||||
columnref map[string]int
|
|
||||||
ColumnsType []reflect.Type
|
|
||||||
}
|
|
||||||
|
|
||||||
// StarResultCol 为查询结果集(按列)
|
|
||||||
type StarResultCol struct {
|
|
||||||
Result []interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustBytes 列查询结果转Bytes
|
|
||||||
func (star *StarResultCol) MustBytes() [][]byte {
|
|
||||||
var res [][]byte
|
|
||||||
for _, v := range star.Result {
|
|
||||||
res = append(res, v.([]byte))
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustBool 列查询结果转Bool
|
|
||||||
func (star *StarResultCol) MustBool() []bool {
|
|
||||||
var res []bool
|
|
||||||
var tmp bool
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = false
|
|
||||||
case bool:
|
|
||||||
tmp = vtype
|
|
||||||
case float64:
|
|
||||||
if vtype > 0 {
|
|
||||||
tmp = true
|
|
||||||
} else {
|
|
||||||
tmp = false
|
|
||||||
}
|
|
||||||
case float32:
|
|
||||||
if vtype > 0 {
|
|
||||||
tmp = true
|
|
||||||
} else {
|
|
||||||
tmp = false
|
|
||||||
}
|
|
||||||
case int:
|
|
||||||
if vtype > 0 {
|
|
||||||
tmp = true
|
|
||||||
} else {
|
|
||||||
tmp = false
|
|
||||||
}
|
|
||||||
case int32:
|
|
||||||
if vtype > 0 {
|
|
||||||
tmp = true
|
|
||||||
} else {
|
|
||||||
tmp = false
|
|
||||||
}
|
|
||||||
case int64:
|
|
||||||
if vtype > 0 {
|
|
||||||
tmp = true
|
|
||||||
} else {
|
|
||||||
tmp = false
|
|
||||||
}
|
|
||||||
case string:
|
|
||||||
tmp, _ = strconv.ParseBool(vtype)
|
|
||||||
default:
|
|
||||||
tmp, _ = strconv.ParseBool(string(vtype.([]byte)))
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustFloat32 列查询结果转Float32
|
|
||||||
func (star *StarResultCol) MustFloat32() []float32 {
|
|
||||||
var res []float32
|
|
||||||
var tmp float32
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = 0
|
|
||||||
case float32:
|
|
||||||
tmp = vtype
|
|
||||||
case float64:
|
|
||||||
tmp = float32(vtype)
|
|
||||||
case string:
|
|
||||||
tmps, _ := strconv.ParseFloat(vtype, 32)
|
|
||||||
tmp = float32(tmps)
|
|
||||||
case int:
|
|
||||||
tmp = float32(vtype)
|
|
||||||
case int32:
|
|
||||||
tmp = float32(vtype)
|
|
||||||
case int64:
|
|
||||||
tmp = float32(vtype)
|
|
||||||
case time.Time:
|
|
||||||
tmp = float32(vtype.Unix())
|
|
||||||
default:
|
|
||||||
tmpt := string(vtype.([]byte))
|
|
||||||
tmps, _ := strconv.ParseFloat(tmpt, 32)
|
|
||||||
tmp = float32(tmps)
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustFloat64 列查询结果转Float64
|
|
||||||
func (star *StarResultCol) MustFloat64() []float64 {
|
|
||||||
var res []float64
|
|
||||||
var tmp float64
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = 0
|
|
||||||
case float64:
|
|
||||||
tmp = vtype
|
|
||||||
case float32:
|
|
||||||
tmp = float64(vtype)
|
|
||||||
case string:
|
|
||||||
tmp, _ = strconv.ParseFloat(vtype, 64)
|
|
||||||
case int:
|
|
||||||
tmp = float64(vtype)
|
|
||||||
case int32:
|
|
||||||
tmp = float64(vtype)
|
|
||||||
case int64:
|
|
||||||
tmp = float64(vtype)
|
|
||||||
case time.Time:
|
|
||||||
tmp = float64(vtype.Unix())
|
|
||||||
default:
|
|
||||||
tmpt := string(vtype.([]byte))
|
|
||||||
tmps, _ := strconv.ParseFloat(tmpt, 64)
|
|
||||||
tmp = float64(tmps)
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustString 列查询结果转String
|
|
||||||
func (star *StarResultCol) MustString() []string {
|
|
||||||
var res []string
|
|
||||||
var tmp string
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = ""
|
|
||||||
case string:
|
|
||||||
tmp = vtype
|
|
||||||
case int64:
|
|
||||||
tmp = strconv.FormatInt(vtype, 10)
|
|
||||||
case int32:
|
|
||||||
tmp = strconv.Itoa(int(vtype))
|
|
||||||
case bool:
|
|
||||||
tmp = strconv.FormatBool(vtype)
|
|
||||||
case float64:
|
|
||||||
tmp = strconv.FormatFloat(vtype, 'f', 10, 64)
|
|
||||||
case float32:
|
|
||||||
tmp = strconv.FormatFloat(float64(vtype), 'f', 10, 32)
|
|
||||||
case int:
|
|
||||||
tmp = strconv.Itoa(vtype)
|
|
||||||
case time.Time:
|
|
||||||
tmp = vtype.String()
|
|
||||||
default:
|
|
||||||
tmp = string(vtype.([]byte))
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustInt32 列查询结果转Int32
|
|
||||||
func (star *StarResultCol) MustInt32() []int32 {
|
|
||||||
var res []int32
|
|
||||||
var tmp int32
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = 0
|
|
||||||
case float64:
|
|
||||||
tmp = int32(vtype)
|
|
||||||
case float32:
|
|
||||||
tmp = int32(vtype)
|
|
||||||
case string:
|
|
||||||
tmps, _ := strconv.ParseInt(vtype, 10, 32)
|
|
||||||
tmp = int32(tmps)
|
|
||||||
case int:
|
|
||||||
tmp = int32(vtype)
|
|
||||||
case int64:
|
|
||||||
tmp = int32(vtype)
|
|
||||||
case int32:
|
|
||||||
tmp = vtype
|
|
||||||
case time.Time:
|
|
||||||
tmp = int32(vtype.Unix())
|
|
||||||
default:
|
|
||||||
tmpt := string(vtype.([]byte))
|
|
||||||
tmps, _ := strconv.ParseInt(tmpt, 10, 32)
|
|
||||||
tmp = int32(tmps)
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustInt64 列查询结果转Int64
|
|
||||||
func (star *StarResultCol) MustInt64() []int64 {
|
|
||||||
var res []int64
|
|
||||||
var tmp int64
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = 0
|
|
||||||
case float64:
|
|
||||||
tmp = int64(vtype)
|
|
||||||
case float32:
|
|
||||||
tmp = int64(vtype)
|
|
||||||
case string:
|
|
||||||
tmps, _ := strconv.ParseInt(vtype, 10, 64)
|
|
||||||
tmp = int64(tmps)
|
|
||||||
case int:
|
|
||||||
tmp = int64(vtype)
|
|
||||||
case int32:
|
|
||||||
tmp = int64(vtype)
|
|
||||||
case int64:
|
|
||||||
tmp = vtype
|
|
||||||
case time.Time:
|
|
||||||
tmp = vtype.Unix()
|
|
||||||
default:
|
|
||||||
tmpt := string(vtype.([]byte))
|
|
||||||
tmp, _ = strconv.ParseInt(tmpt, 10, 64)
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustInt 列查询结果转Int
|
|
||||||
func (star *StarResultCol) MustInt() []int {
|
|
||||||
var res []int
|
|
||||||
var tmp int
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = 0
|
|
||||||
case float64:
|
|
||||||
tmp = int(vtype)
|
|
||||||
case float32:
|
|
||||||
tmp = int(vtype)
|
|
||||||
case string:
|
|
||||||
tmps, _ := strconv.ParseInt(vtype, 10, 64)
|
|
||||||
tmp = int(tmps)
|
|
||||||
case int:
|
|
||||||
tmp = vtype
|
|
||||||
case int32:
|
|
||||||
tmp = int(vtype)
|
|
||||||
case int64:
|
|
||||||
tmp = int(vtype)
|
|
||||||
case time.Time:
|
|
||||||
tmp = int(vtype.Unix())
|
|
||||||
default:
|
|
||||||
tmpt := string(vtype.([]byte))
|
|
||||||
tmps, _ := strconv.ParseInt(tmpt, 10, 64)
|
|
||||||
tmp = int(tmps)
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustDate 列查询结果转Date(time.Time)
|
|
||||||
func (star *StarResultCol) MustDate(layout string) []time.Time {
|
|
||||||
var res []time.Time
|
|
||||||
var tmp time.Time
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = time.Time{}
|
|
||||||
case float64:
|
|
||||||
tmp = time.Unix(int64(vtype), int64(vtype-float64(int64(vtype)))*1000000000)
|
|
||||||
case float32:
|
|
||||||
tmp = time.Unix(int64(vtype), int64(vtype-float32(int64(vtype)))*1000000000)
|
|
||||||
case string:
|
|
||||||
tmp, _ = time.Parse(layout, vtype)
|
|
||||||
case int:
|
|
||||||
tmp = time.Unix(int64(vtype), 0)
|
|
||||||
case int32:
|
|
||||||
tmp = time.Unix(int64(vtype), 0)
|
|
||||||
case int64:
|
|
||||||
tmp = time.Unix(vtype, 0)
|
|
||||||
case time.Time:
|
|
||||||
tmp = vtype
|
|
||||||
default:
|
|
||||||
tmpt := string(vtype.([]byte))
|
|
||||||
tmp, _ = time.Parse(layout, tmpt)
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNil 检测是不是nil 列查询结果是不是nil
|
|
||||||
func (star *StarResultCol) IsNil(name string) []bool {
|
|
||||||
var res []bool
|
|
||||||
var tmp bool
|
|
||||||
for _, v := range star.Result {
|
|
||||||
switch v.(type) {
|
|
||||||
case nil:
|
|
||||||
tmp = true
|
|
||||||
default:
|
|
||||||
tmp = false
|
|
||||||
}
|
|
||||||
res = append(res, tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNil 检测是不是nil
|
|
||||||
func (star *StarResult) IsNil(name string) bool {
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tmp := star.Result[num]
|
|
||||||
switch tmp.(type) {
|
|
||||||
case nil:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustDate 列查询结果转Date
|
|
||||||
func (star *StarResult) MustDate(name, layout string) time.Time {
|
|
||||||
var res time.Time
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
tmp := star.Result[num]
|
|
||||||
switch vtype := tmp.(type) {
|
|
||||||
case nil:
|
|
||||||
res = time.Time{}
|
|
||||||
case float64:
|
|
||||||
res = time.Unix(int64(vtype), int64(vtype-float64(int64(vtype)))*1000000000)
|
|
||||||
case float32:
|
|
||||||
res = time.Unix(int64(vtype), int64(vtype-float32(int64(vtype)))*1000000000)
|
|
||||||
case string:
|
|
||||||
res, _ = time.Parse(layout, vtype)
|
|
||||||
case int:
|
|
||||||
res = time.Unix(int64(vtype), 0)
|
|
||||||
case int32:
|
|
||||||
res = time.Unix(int64(vtype), 0)
|
|
||||||
case int64:
|
|
||||||
res = time.Unix(vtype, 0)
|
|
||||||
case time.Time:
|
|
||||||
res = vtype
|
|
||||||
default:
|
|
||||||
res, _ = time.Parse(layout, string(tmp.([]byte)))
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustInt64 列查询结果转int64
|
|
||||||
func (star *StarResult) MustInt64(name string) int64 {
|
|
||||||
var res int64
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
tmp := star.Result[num]
|
|
||||||
switch vtype := tmp.(type) {
|
|
||||||
case nil:
|
|
||||||
res = 0
|
|
||||||
case float64:
|
|
||||||
res = int64(vtype)
|
|
||||||
case float32:
|
|
||||||
res = int64(vtype)
|
|
||||||
case string:
|
|
||||||
res, _ = strconv.ParseInt(vtype, 10, 64)
|
|
||||||
case int:
|
|
||||||
res = int64(vtype)
|
|
||||||
case int32:
|
|
||||||
res = int64(vtype)
|
|
||||||
case int64:
|
|
||||||
res = vtype
|
|
||||||
case time.Time:
|
|
||||||
res = int64(vtype.Unix())
|
|
||||||
default:
|
|
||||||
res, _ = strconv.ParseInt(string(tmp.([]byte)), 10, 64)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustInt32 列查询结果转Int32
|
|
||||||
func (star *StarResult) MustInt32(name string) int32 {
|
|
||||||
var res int32
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
tmp := star.Result[num]
|
|
||||||
switch vtype := tmp.(type) {
|
|
||||||
case nil:
|
|
||||||
res = 0
|
|
||||||
case float64:
|
|
||||||
res = int32(vtype)
|
|
||||||
case float32:
|
|
||||||
res = int32(vtype)
|
|
||||||
case string:
|
|
||||||
ress, _ := strconv.ParseInt(vtype, 10, 32)
|
|
||||||
res = int32(ress)
|
|
||||||
case int:
|
|
||||||
res = int32(vtype)
|
|
||||||
case int32:
|
|
||||||
res = vtype
|
|
||||||
case int64:
|
|
||||||
res = int32(vtype)
|
|
||||||
case time.Time:
|
|
||||||
res = int32(vtype.Unix())
|
|
||||||
default:
|
|
||||||
ress, _ := strconv.ParseInt(string(tmp.([]byte)), 10, 32)
|
|
||||||
res = int32(ress)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustString 列查询结果转string
|
|
||||||
func (star *StarResult) MustString(name string) string {
|
|
||||||
var res string
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
switch vtype := star.Result[num].(type) {
|
|
||||||
case nil:
|
|
||||||
res = ""
|
|
||||||
case string:
|
|
||||||
res = vtype
|
|
||||||
case int64:
|
|
||||||
res = strconv.FormatInt(vtype, 10)
|
|
||||||
case int32:
|
|
||||||
res = strconv.Itoa(int(vtype))
|
|
||||||
case bool:
|
|
||||||
res = strconv.FormatBool(vtype)
|
|
||||||
case float64:
|
|
||||||
res = strconv.FormatFloat(vtype, 'f', 10, 64)
|
|
||||||
case float32:
|
|
||||||
res = strconv.FormatFloat(float64(vtype), 'f', 10, 32)
|
|
||||||
case int:
|
|
||||||
res = strconv.Itoa(vtype)
|
|
||||||
case time.Time:
|
|
||||||
res = vtype.String()
|
|
||||||
default:
|
|
||||||
res = string(vtype.([]byte))
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustFloat64 列查询结果转float64
|
|
||||||
func (star *StarResult) MustFloat64(name string) float64 {
|
|
||||||
var res float64
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
switch vtype := star.Result[num].(type) {
|
|
||||||
case nil:
|
|
||||||
res = 0
|
|
||||||
case string:
|
|
||||||
res, _ = strconv.ParseFloat(vtype, 64)
|
|
||||||
case float64:
|
|
||||||
res = vtype
|
|
||||||
case int:
|
|
||||||
res = float64(vtype)
|
|
||||||
case int64:
|
|
||||||
res = float64(vtype)
|
|
||||||
case int32:
|
|
||||||
res = float64(vtype)
|
|
||||||
case float32:
|
|
||||||
res = float64(vtype)
|
|
||||||
case time.Time:
|
|
||||||
res = float64(vtype.Unix())
|
|
||||||
default:
|
|
||||||
res, _ = strconv.ParseFloat(string(vtype.([]byte)), 64)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustFloat32 列查询结果转float32
|
|
||||||
func (star *StarResult) MustFloat32(name string) float32 {
|
|
||||||
var res float32
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
switch vtype := star.Result[num].(type) {
|
|
||||||
case nil:
|
|
||||||
res = 0
|
|
||||||
case string:
|
|
||||||
tmp, _ := strconv.ParseFloat(vtype, 32)
|
|
||||||
res = float32(tmp)
|
|
||||||
case float64:
|
|
||||||
res = float32(vtype)
|
|
||||||
case float32:
|
|
||||||
res = vtype
|
|
||||||
case int:
|
|
||||||
res = float32(vtype)
|
|
||||||
case int64:
|
|
||||||
res = float32(vtype)
|
|
||||||
case int32:
|
|
||||||
res = float32(vtype)
|
|
||||||
case time.Time:
|
|
||||||
res = float32(vtype.Unix())
|
|
||||||
default:
|
|
||||||
tmp, _ := strconv.ParseFloat(string(vtype.([]byte)), 32)
|
|
||||||
res = float32(tmp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustInt 列查询结果转int
|
|
||||||
func (star *StarResult) MustInt(name string) int {
|
|
||||||
var res int
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
tmp := star.Result[num]
|
|
||||||
switch vtype := tmp.(type) {
|
|
||||||
case nil:
|
|
||||||
res = 0
|
|
||||||
case float64:
|
|
||||||
res = int(vtype)
|
|
||||||
case float32:
|
|
||||||
res = int(vtype)
|
|
||||||
case string:
|
|
||||||
ress, _ := strconv.ParseInt(vtype, 10, 64)
|
|
||||||
res = int(ress)
|
|
||||||
case int:
|
|
||||||
res = vtype
|
|
||||||
case int32:
|
|
||||||
res = int(vtype)
|
|
||||||
case int64:
|
|
||||||
res = int(vtype)
|
|
||||||
case time.Time:
|
|
||||||
res = int(vtype.Unix())
|
|
||||||
default:
|
|
||||||
ress, _ := strconv.ParseInt(string(tmp.([]byte)), 10, 64)
|
|
||||||
res = int(ress)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustBool 列查询结果转bool
|
|
||||||
func (star *StarResult) MustBool(name string) bool {
|
|
||||||
var res bool
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tmp := star.Result[num]
|
|
||||||
switch vtype := tmp.(type) {
|
|
||||||
case nil:
|
|
||||||
res = false
|
|
||||||
case bool:
|
|
||||||
res = vtype
|
|
||||||
case float64:
|
|
||||||
if vtype > 0 {
|
|
||||||
res = true
|
|
||||||
} else {
|
|
||||||
res = false
|
|
||||||
}
|
|
||||||
case float32:
|
|
||||||
if vtype > 0 {
|
|
||||||
res = true
|
|
||||||
} else {
|
|
||||||
res = false
|
|
||||||
}
|
|
||||||
case int:
|
|
||||||
if vtype > 0 {
|
|
||||||
res = true
|
|
||||||
} else {
|
|
||||||
res = false
|
|
||||||
}
|
|
||||||
case int32:
|
|
||||||
if vtype > 0 {
|
|
||||||
res = true
|
|
||||||
} else {
|
|
||||||
res = false
|
|
||||||
}
|
|
||||||
case int64:
|
|
||||||
if vtype > 0 {
|
|
||||||
res = true
|
|
||||||
} else {
|
|
||||||
res = false
|
|
||||||
}
|
|
||||||
case string:
|
|
||||||
res, _ = strconv.ParseBool(vtype)
|
|
||||||
default:
|
|
||||||
res, _ = strconv.ParseBool(string(vtype.([]byte)))
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustBytes 列查询结果转byte
|
|
||||||
func (star *StarResult) MustBytes(name string) []byte {
|
|
||||||
num, ok := star.columnref[name]
|
|
||||||
if !ok {
|
|
||||||
return []byte{}
|
|
||||||
}
|
|
||||||
res := star.Result[num].([]byte)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rescan 重新分析结果集
|
|
||||||
func (star *StarRows) Rescan() {
|
|
||||||
star.parserows()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Col 选择需要进行操作的数据结果列
|
|
||||||
func (star *StarRows) Col(name string) *StarResultCol {
|
|
||||||
result := new(StarResultCol)
|
|
||||||
if _, ok := star.columnref[name]; !ok {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
var rescol []interface{}
|
|
||||||
for _, v := range star.result {
|
|
||||||
rescol = append(rescol, v[star.columnref[name]])
|
|
||||||
}
|
|
||||||
result.Result = rescol
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// Row 选择需要进行操作的数据结果行
|
|
||||||
func (star *StarRows) Row(id int) *StarResult {
|
|
||||||
result := new(StarResult)
|
|
||||||
if id+1 > len(star.result) {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
result.Result = star.result[id]
|
|
||||||
result.Columns = star.Columns
|
|
||||||
result.ColumnsType = star.ColumnsType
|
|
||||||
result.columnref = star.columnref
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close 关闭打开的结果集
|
|
||||||
func (star *StarRows) Close() error {
|
|
||||||
return star.Rows.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (star *StarRows) parserows() {
|
|
||||||
star.result = [][]interface{}{}
|
|
||||||
star.columnref = make(map[string]int)
|
|
||||||
star.StringResult = []map[string]string{}
|
|
||||||
star.Columns, _ = star.Rows.Columns()
|
|
||||||
types, _ := star.Rows.ColumnTypes()
|
|
||||||
for _, v := range types {
|
|
||||||
star.ColumnsType = append(star.ColumnsType, v.ScanType())
|
|
||||||
}
|
|
||||||
scanArgs := make([]interface{}, len(star.Columns))
|
|
||||||
values := make([]interface{}, len(star.Columns))
|
|
||||||
for i := range values {
|
|
||||||
star.columnref[star.Columns[i]] = i
|
|
||||||
scanArgs[i] = &values[i]
|
|
||||||
}
|
|
||||||
for star.Rows.Next() {
|
|
||||||
if err := star.Rows.Scan(scanArgs...); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
record := make(map[string]string)
|
|
||||||
var rescopy []interface{}
|
|
||||||
for i, col := range values {
|
|
||||||
rescopy = append(rescopy, col)
|
|
||||||
switch vtype := col.(type) {
|
|
||||||
case float32:
|
|
||||||
record[star.Columns[i]] = strconv.FormatFloat(float64(vtype), 'f', -1, 64)
|
|
||||||
case float64:
|
|
||||||
record[star.Columns[i]] = strconv.FormatFloat(vtype, 'f', -1, 64)
|
|
||||||
case int64:
|
|
||||||
record[star.Columns[i]] = strconv.FormatInt(vtype, 10)
|
|
||||||
case int32:
|
|
||||||
record[star.Columns[i]] = strconv.FormatInt(int64(vtype), 10)
|
|
||||||
case int:
|
|
||||||
record[star.Columns[i]] = strconv.Itoa(vtype)
|
|
||||||
case string:
|
|
||||||
record[star.Columns[i]] = vtype
|
|
||||||
case bool:
|
|
||||||
record[star.Columns[i]] = strconv.FormatBool(vtype)
|
|
||||||
case time.Time:
|
|
||||||
record[star.Columns[i]] = vtype.String()
|
|
||||||
case nil:
|
|
||||||
record[star.Columns[i]] = ""
|
|
||||||
default:
|
|
||||||
record[star.Columns[i]] = string(vtype.([]byte))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
star.result = append(star.result, rescopy)
|
|
||||||
star.StringResult = append(star.StringResult, record)
|
|
||||||
}
|
|
||||||
star.Length = len(star.StringResult)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query 进行Query操作
|
|
||||||
func (star *StarDB) Query(args ...interface{}) (*StarRows, error) {
|
|
||||||
var err error
|
|
||||||
effect := new(StarRows)
|
|
||||||
if err = star.DB.Ping(); err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
if len(args) == 0 {
|
|
||||||
return effect, errors.New("no args")
|
|
||||||
}
|
|
||||||
if len(args) == 1 {
|
|
||||||
sql := args[0]
|
|
||||||
if star.Rows, err = star.DB.Query(sql.(string)); err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
effect.Rows = star.Rows
|
|
||||||
effect.parserows()
|
|
||||||
return effect, nil
|
|
||||||
}
|
|
||||||
sql := args[0]
|
|
||||||
stmt, err := star.DB.Prepare(sql.(string))
|
|
||||||
if err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
defer stmt.Close()
|
|
||||||
var para []interface{}
|
|
||||||
for k, v := range args {
|
|
||||||
if k != 0 {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
default:
|
|
||||||
para = append(para, vtype)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if star.Rows, err = stmt.Query(para...); err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
effect.Rows = star.Rows
|
|
||||||
effect.parserows()
|
|
||||||
return effect, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open 打开一个新的数据库
|
|
||||||
func (star *StarDB) Open(Method, ConnStr string) error {
|
|
||||||
var err error
|
|
||||||
star.DB, err = sql.Open(Method, ConnStr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = star.DB.Ping()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close 关闭打开的数据库
|
|
||||||
func (star *StarDB) Close() error {
|
|
||||||
if err := star.DB.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return star.DB.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exec 执行Exec操作
|
|
||||||
func (star *StarDB) Exec(args ...interface{}) (sql.Result, error) {
|
|
||||||
var err error
|
|
||||||
var effect sql.Result
|
|
||||||
if err = star.DB.Ping(); err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
if len(args) == 0 {
|
|
||||||
return effect, errors.New("no args")
|
|
||||||
}
|
|
||||||
if len(args) == 1 {
|
|
||||||
sql := args[0]
|
|
||||||
if _, err = star.DB.Exec(sql.(string)); err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
return effect, nil
|
|
||||||
}
|
|
||||||
sql := args[0]
|
|
||||||
stmt, err := star.DB.Prepare(sql.(string))
|
|
||||||
if err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
defer stmt.Close()
|
|
||||||
var para []interface{}
|
|
||||||
for k, v := range args {
|
|
||||||
if k != 0 {
|
|
||||||
switch vtype := v.(type) {
|
|
||||||
default:
|
|
||||||
para = append(para, vtype)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if effect, err = stmt.Exec(para...); err != nil {
|
|
||||||
return effect, err
|
|
||||||
}
|
|
||||||
return effect, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchAll 把结果集全部转为key-value型<string>数据
|
|
||||||
func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) {
|
func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) {
|
||||||
var ii int = 0
|
var ii int = 0
|
||||||
records := make(map[int]map[string]string)
|
records := make(map[int]map[string]string)
|
||||||
@ -857,8 +31,6 @@ func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) {
|
|||||||
record[columns[i]] = strconv.FormatInt(vtype, 10)
|
record[columns[i]] = strconv.FormatInt(vtype, 10)
|
||||||
case string:
|
case string:
|
||||||
record[columns[i]] = vtype
|
record[columns[i]] = vtype
|
||||||
case nil:
|
|
||||||
record[columns[i]] = ""
|
|
||||||
default:
|
default:
|
||||||
record[columns[i]] = string(vtype.([]byte))
|
record[columns[i]] = string(vtype.([]byte))
|
||||||
}
|
}
|
||||||
@ -869,7 +41,6 @@ func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) {
|
|||||||
return nil, records
|
return nil, records
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenDB 打开一个数据库
|
|
||||||
func OpenDB(Method, ConnStr string) error {
|
func OpenDB(Method, ConnStr string) error {
|
||||||
var err error
|
var err error
|
||||||
DBRes, err = sql.Open(Method, ConnStr)
|
DBRes, err = sql.Open(Method, ConnStr)
|
||||||
@ -879,14 +50,11 @@ func OpenDB(Method, ConnStr string) error {
|
|||||||
err = DBRes.Ping()
|
err = DBRes.Ping()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloseDB 关闭打开的数据库
|
|
||||||
func CloseDB() {
|
func CloseDB() {
|
||||||
DBRes.Close()
|
DBRes.Close()
|
||||||
DBRows.Close()
|
DBRows.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query 进行数据库查询操作
|
|
||||||
func Query(args ...interface{}) (error, map[int]map[string]string) {
|
func Query(args ...interface{}) (error, map[int]map[string]string) {
|
||||||
var err error
|
var err error
|
||||||
records := make(map[int]map[string]string)
|
records := make(map[int]map[string]string)
|
||||||
@ -925,7 +93,6 @@ func Query(args ...interface{}) (error, map[int]map[string]string) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBExec 进行数据库EXEC查询操作
|
|
||||||
func DBExec(args ...interface{}) error {
|
func DBExec(args ...interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
if err = DBRes.Ping(); err != nil {
|
if err = DBRes.Ping(); err != nil {
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDataBase(t *testing.T) {
|
|
||||||
mysql := new(StarDB)
|
|
||||||
defer mysql.Close()
|
|
||||||
mysql.Open("sqlite3", "D:\\Ttest.db")
|
|
||||||
mysql.Exec("CREATE TABLE IF NOT EXISTS sakura(id INT PRIMARY KEY,xihuan TEXT)")
|
|
||||||
mysql.Exec("INSERT INTO sakura VALUES(?,?)", 2, "dssfsdfdf")
|
|
||||||
sakura, _ := mysql.Query("SELECT * FROM sakura")
|
|
||||||
defer sakura.Close()
|
|
||||||
fmt.Println(sakura.Row(0).MustString("xihuan"))
|
|
||||||
}
|
|
421
http.go
421
http.go
@ -1,421 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime/multipart"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
urls "net/url"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StarCurl struct {
|
|
||||||
TimeOut int
|
|
||||||
DialTimeOut int
|
|
||||||
ReqHeader http.Header
|
|
||||||
ReqCookies []*http.Cookie
|
|
||||||
RespHeader http.Header
|
|
||||||
RespCookies []*http.Cookie
|
|
||||||
RespHttpCode int
|
|
||||||
PostBuffer *bytes.Buffer
|
|
||||||
CircleBuffer *CircleByteBuffer
|
|
||||||
Proxy string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStarCurl() *StarCurl {
|
|
||||||
star := new(StarCurl)
|
|
||||||
star.ReqHeader = make(http.Header)
|
|
||||||
star.TimeOut = 60
|
|
||||||
star.DialTimeOut = 15
|
|
||||||
star.PostBuffer = nil
|
|
||||||
return star
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) ResetReqHeader() {
|
|
||||||
this.ReqHeader = make(http.Header)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) ResetReqCookies() {
|
|
||||||
this.ReqCookies = []*http.Cookie{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) AddSimpleCookie(key, value string) {
|
|
||||||
this.ReqCookies = append(this.ReqCookies, &http.Cookie{Name: key, Value: value, Path: "/"})
|
|
||||||
}
|
|
||||||
|
|
||||||
func randomBoundary() string {
|
|
||||||
var buf [30]byte
|
|
||||||
_, err := io.ReadFull(rand.Reader, buf[:])
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%x", buf[:])
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) CurlWithFile(url string, postdata map[string]string, formname, fpath, savepath string, tofile bool, shell func(float64)) (result []byte, err error) {
|
|
||||||
fpsrc, err := os.Open(fpath)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer fpsrc.Close()
|
|
||||||
boundary := randomBoundary()
|
|
||||||
boundarybytes := []byte("\r\n--" + boundary + "\r\n")
|
|
||||||
endbytes := []byte("\r\n--" + boundary + "--\r\n")
|
|
||||||
fpstat, _ := os.Stat(fpath)
|
|
||||||
filebig := float64(fpstat.Size())
|
|
||||||
sum, n := 0, 0
|
|
||||||
fpdst := NewCircleByteBuffer(1048576)
|
|
||||||
if postdata != nil {
|
|
||||||
for k, v := range postdata {
|
|
||||||
header := fmt.Sprintf("Content-Disposition: form-data; name=\"%s\";\r\nContent-Type: x-www-form-urlencoded \r\n\r\n", k)
|
|
||||||
fpdst.Write(boundarybytes)
|
|
||||||
fpdst.Write([]byte(header))
|
|
||||||
fpdst.Write([]byte(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
header := fmt.Sprintf("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n", formname, fpstat.Name())
|
|
||||||
fpdst.Write(boundarybytes)
|
|
||||||
fpdst.Write([]byte(header))
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
bufs := make([]byte, 393213)
|
|
||||||
n, err = fpsrc.Read(bufs)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
if n != 0 {
|
|
||||||
fpdst.Write(bufs[0:n])
|
|
||||||
go shell(float64(sum+n) / filebig * 100)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sum += n
|
|
||||||
go shell(float64(sum) / filebig * 100)
|
|
||||||
fpdst.Write(bufs[0:n])
|
|
||||||
}
|
|
||||||
fpdst.Write(endbytes)
|
|
||||||
fpdst.Write(nil)
|
|
||||||
}()
|
|
||||||
this.CircleBuffer = fpdst
|
|
||||||
this.ReqHeader.Set("Content-Type", "multipart/form-data;boundary="+boundary)
|
|
||||||
if tofile {
|
|
||||||
err = this.CurlDataToFile(url, []byte{}, "POST", savepath, shell)
|
|
||||||
this.ResetReqHeader()
|
|
||||||
} else {
|
|
||||||
result, err = this.Curl(url, []byte{}, "POST")
|
|
||||||
}
|
|
||||||
this.ResetReqHeader()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) CurlWithFileByBytes(url string, postdata map[string]string, formname, fname string, data []byte, savepath string, tofile bool) (result []byte, err error) {
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
bufwriter := multipart.NewWriter(buf)
|
|
||||||
if postdata != nil {
|
|
||||||
for k, v := range postdata {
|
|
||||||
bufwriter.WriteField(k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fpdst, err := bufwriter.CreateFormFile(formname, fname)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fpdst.Write(data)
|
|
||||||
this.PostBuffer = buf
|
|
||||||
this.ReqHeader.Set("Content-Type", "multipart/form-data;boundary="+bufwriter.Boundary())
|
|
||||||
bufwriter.Close()
|
|
||||||
if tofile {
|
|
||||||
err = this.CurlDataToFile(url, []byte{}, "POST", savepath, func(float64) {})
|
|
||||||
this.ResetReqHeader()
|
|
||||||
} else {
|
|
||||||
result, err = this.Curl(url, []byte{}, "POST")
|
|
||||||
}
|
|
||||||
this.ResetReqHeader()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) CurlWithFileByMemory(url string, postdata map[string]string, formname, fpath, savepath string, tofile bool, shell func(float64)) (result []byte, err error) {
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
bufwriter := multipart.NewWriter(buf)
|
|
||||||
if postdata != nil {
|
|
||||||
for k, v := range postdata {
|
|
||||||
bufwriter.WriteField(k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fpdst, err := bufwriter.CreateFormFile(formname, filepath.Base(fpath))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fpsrc, err := os.Open(fpath)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer fpsrc.Close()
|
|
||||||
fpstat, _ := os.Stat(fpath)
|
|
||||||
filebig := float64(fpstat.Size())
|
|
||||||
sum, n := 0, 0
|
|
||||||
for {
|
|
||||||
bufs := make([]byte, 393213)
|
|
||||||
n, err = fpsrc.Read(bufs)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
if n != 0 {
|
|
||||||
fpdst.Write(bufs[0:n])
|
|
||||||
go shell(float64(sum+n) / filebig * 100)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sum += n
|
|
||||||
go shell(float64(sum) / filebig * 100)
|
|
||||||
fpdst.Write(bufs[0:n])
|
|
||||||
}
|
|
||||||
|
|
||||||
this.PostBuffer = buf
|
|
||||||
this.ReqHeader.Set("Content-Type", "multipart/form-data;boundary="+bufwriter.Boundary())
|
|
||||||
bufwriter.Close()
|
|
||||||
if tofile {
|
|
||||||
err = this.CurlDataToFile(url, []byte{}, "POST", savepath, shell)
|
|
||||||
this.ResetReqHeader()
|
|
||||||
} else {
|
|
||||||
result, err = this.Curl(url, []byte{}, "POST")
|
|
||||||
}
|
|
||||||
this.ResetReqHeader()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) CurlDataToFile(url string, postdata []byte, method, fpath string, shell func(float64)) (err error) {
|
|
||||||
var req *http.Request
|
|
||||||
if method == "" {
|
|
||||||
if len(postdata) != 0 {
|
|
||||||
method = "POST"
|
|
||||||
} else {
|
|
||||||
method = "GET"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(postdata) == 0 && this.PostBuffer == nil && this.CircleBuffer == nil {
|
|
||||||
req, err = http.NewRequest(method, url, nil)
|
|
||||||
} else if len(postdata) != 0 {
|
|
||||||
req, err = http.NewRequest(method, url, bytes.NewBuffer(postdata))
|
|
||||||
} else if this.PostBuffer != nil {
|
|
||||||
req, err = http.NewRequest(method, url, this.PostBuffer)
|
|
||||||
} else {
|
|
||||||
req, err = http.NewRequest(method, url, this.CircleBuffer)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.ReqHeader == nil) && method == "POST" {
|
|
||||||
this.ReqHeader.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
}
|
|
||||||
req.Header = this.ReqHeader
|
|
||||||
if len(this.ReqCookies) != 0 {
|
|
||||||
for _, v := range this.ReqCookies {
|
|
||||||
req.AddCookie(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transport := &http.Transport{
|
|
||||||
Dial: func(netw, addr string) (net.Conn, error) {
|
|
||||||
deadline := time.Now().Add(time.Duration(this.TimeOut) * time.Second)
|
|
||||||
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(this.DialTimeOut))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if this.TimeOut != 0 {
|
|
||||||
c.SetDeadline(deadline)
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if this.Proxy != "" {
|
|
||||||
purl, _ := urls.Parse(this.Proxy)
|
|
||||||
transport.Proxy = http.ProxyURL(purl)
|
|
||||||
}
|
|
||||||
client := &http.Client{
|
|
||||||
Transport: transport,
|
|
||||||
}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
this.PostBuffer = nil
|
|
||||||
this.CircleBuffer = nil
|
|
||||||
this.RespHttpCode = resp.StatusCode
|
|
||||||
this.RespHeader = resp.Header
|
|
||||||
this.RespCookies = resp.Cookies()
|
|
||||||
fpsrc, err := os.Create(fpath)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer fpsrc.Close()
|
|
||||||
filebig := float64(resp.ContentLength)
|
|
||||||
if filebig <= 0 {
|
|
||||||
filebig = 100
|
|
||||||
}
|
|
||||||
var n, sum int = 0, 0
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 393213)
|
|
||||||
n, err = resp.Body.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
err = nil
|
|
||||||
if n != 0 {
|
|
||||||
fpsrc.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
go shell(100.00)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sum += n
|
|
||||||
go shell(float64(sum) / filebig * 100.00)
|
|
||||||
fpsrc.Write(buf[0:n])
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCurl) Curl(url string, postdata []byte, method string) (body []byte, err error) {
|
|
||||||
var req *http.Request
|
|
||||||
if method == "" {
|
|
||||||
if len(postdata) != 0 {
|
|
||||||
method = "POST"
|
|
||||||
} else {
|
|
||||||
method = "GET"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(postdata) == 0 && this.PostBuffer == nil && this.CircleBuffer == nil {
|
|
||||||
req, err = http.NewRequest(method, url, nil)
|
|
||||||
} else if len(postdata) != 0 {
|
|
||||||
req, err = http.NewRequest(method, url, bytes.NewBuffer(postdata))
|
|
||||||
} else if this.PostBuffer != nil {
|
|
||||||
req, err = http.NewRequest(method, url, this.PostBuffer)
|
|
||||||
} else {
|
|
||||||
req, err = http.NewRequest(method, url, this.CircleBuffer)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.ReqHeader == nil) && method == "POST" {
|
|
||||||
this.ReqHeader.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
}
|
|
||||||
req.Header = this.ReqHeader
|
|
||||||
if len(this.ReqCookies) != 0 {
|
|
||||||
for _, v := range this.ReqCookies {
|
|
||||||
req.AddCookie(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transport := &http.Transport{
|
|
||||||
Dial: func(netw, addr string) (net.Conn, error) {
|
|
||||||
deadline := time.Now().Add(time.Duration(this.TimeOut) * time.Second)
|
|
||||||
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(this.DialTimeOut))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if this.TimeOut != 0 {
|
|
||||||
c.SetDeadline(deadline)
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if this.Proxy != "" {
|
|
||||||
purl, _ := urls.Parse(this.Proxy)
|
|
||||||
transport.Proxy = http.ProxyURL(purl)
|
|
||||||
}
|
|
||||||
client := &http.Client{
|
|
||||||
Transport: transport,
|
|
||||||
}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
this.PostBuffer = nil
|
|
||||||
this.CircleBuffer = nil
|
|
||||||
this.RespHttpCode = resp.StatusCode
|
|
||||||
this.RespHeader = resp.Header
|
|
||||||
this.RespCookies = resp.Cookies()
|
|
||||||
body, err = ioutil.ReadAll(resp.Body)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//HttpNulReset将重置Header和Cookie为空
|
|
||||||
func HttpNulReset() {
|
|
||||||
var tmp map[string]string
|
|
||||||
HttpNul, HttpNul2 = tmp, tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
func Curl(url string, postdata string, header map[string]string, cookie map[string]string, method string) (error, int, []byte, http.Header, []*http.Cookie) {
|
|
||||||
var req *http.Request
|
|
||||||
if method == "" {
|
|
||||||
if len(postdata) != 0 {
|
|
||||||
method = "POST"
|
|
||||||
} else {
|
|
||||||
method = "GET"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BytePostData := []byte(postdata)
|
|
||||||
if postdata == "" || len(postdata) == 0 {
|
|
||||||
req, _ = http.NewRequest(method, url, nil)
|
|
||||||
} else {
|
|
||||||
req, _ = http.NewRequest(method, url, bytes.NewBuffer(BytePostData))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len(header) == 0 || header == nil) && method == "POST" {
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
}
|
|
||||||
for k, v := range header {
|
|
||||||
req.Header.Set(k, v)
|
|
||||||
}
|
|
||||||
if len(cookie) != 0 {
|
|
||||||
for k, v := range cookie {
|
|
||||||
req.AddCookie(&http.Cookie{Name: k, Value: v, HttpOnly: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
client := &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Dial: func(netw, addr string) (net.Conn, error) {
|
|
||||||
deadline := time.Now().Add(time.Duration(HttpTimeOut) * time.Second)
|
|
||||||
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(HttpTimeOut))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.SetDeadline(deadline)
|
|
||||||
return c, nil
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
var rte []*http.Cookie
|
|
||||||
if err != nil {
|
|
||||||
return err, 0, []byte(""), req.Header, rte
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
statuscode := resp.StatusCode
|
|
||||||
hea := resp.Header
|
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
return nil, statuscode, body, hea, resp.Cookies()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//CurlGet发起一个HTTP GET请求
|
|
||||||
func CurlGet(url string) (error, []byte) {
|
|
||||||
err, _, res, _, _ := Curl(url, "", HttpNul, HttpNul2, "GET")
|
|
||||||
return err, res
|
|
||||||
}
|
|
||||||
|
|
||||||
//CurlPost发起一个基于表单的HTTP Post请求
|
|
||||||
func CurlPost(url, postdata string) (error, []byte) {
|
|
||||||
err, _, res, _, _ := Curl(url, postdata, HttpNul, HttpNul2, "POST")
|
|
||||||
return err, res
|
|
||||||
}
|
|
471
ini.go
471
ini.go
@ -3,13 +3,10 @@ package starainrt
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -162,7 +159,7 @@ jump:
|
|||||||
if ok, _ := regexp.MatchString("^#", v); ok {
|
if ok, _ := regexp.MatchString("^#", v); ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
segfind := regexp.MustCompile(`^\[(.*)\]`)
|
segfind := regexp.MustCompile(`\[(.*)\]`)
|
||||||
if !inseg {
|
if !inseg {
|
||||||
if ok, _ := regexp.MatchString(`(.*?)=(.*)`, v); ok {
|
if ok, _ := regexp.MatchString(`(.*?)=(.*)`, v); ok {
|
||||||
nolabel = true
|
nolabel = true
|
||||||
@ -198,469 +195,3 @@ jump:
|
|||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type StarCfg struct {
|
|
||||||
Data []*CfgSegment
|
|
||||||
segmap map[string]int
|
|
||||||
//nodemap map[int]map[string]int
|
|
||||||
segid int
|
|
||||||
}
|
|
||||||
|
|
||||||
type CfgNode struct {
|
|
||||||
Key string
|
|
||||||
Value string
|
|
||||||
Comment string
|
|
||||||
}
|
|
||||||
|
|
||||||
type CfgSegment struct {
|
|
||||||
Name string
|
|
||||||
cmap map[string]int
|
|
||||||
Comment string
|
|
||||||
Node []*CfgNode
|
|
||||||
nodeid int
|
|
||||||
//InsertNode []*CfgNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCfg) ParseFromFile(filepath string) error {
|
|
||||||
if !Exists(filepath) {
|
|
||||||
return errors.New(filepath + " 不存在")
|
|
||||||
}
|
|
||||||
data, err := ioutil.ReadFile(filepath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
this.Parse(data)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCfg) WriteToFile(filepath string) error {
|
|
||||||
data := this.Build()
|
|
||||||
return ioutil.WriteFile(filepath, data, 0644)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse 生成INI文件结构
|
|
||||||
func (this *StarCfg) Parse(data []byte) {
|
|
||||||
var newnode *CfgNode
|
|
||||||
this.segid = 0 //segment序号
|
|
||||||
nodeint := 0
|
|
||||||
this.segmap = make(map[string]int) //segment名 序号
|
|
||||||
//this.nodemap = make(map[int]map[string]int)
|
|
||||||
nodemap := make(map[string]int)
|
|
||||||
strdata := string(data) //转换成字符串
|
|
||||||
list := strings.Split(strdata, "\n") //分割
|
|
||||||
newseg := new(CfgSegment)
|
|
||||||
newseg.Name = "unnamed" //默认名
|
|
||||||
//newseg.InsertNode = []*CfgNode{}
|
|
||||||
this.segmap["unnamed"] = 0
|
|
||||||
lastiseg := true
|
|
||||||
for _, v := range list {
|
|
||||||
istrans := false
|
|
||||||
isseg := false //是否为新seg
|
|
||||||
isnote := false //是否为注释
|
|
||||||
isequal := false // 是否为等号
|
|
||||||
tmp1 := []rune{}
|
|
||||||
tmp2 := []rune{}
|
|
||||||
note := []rune{}
|
|
||||||
v = strings.TrimSpace(v)
|
|
||||||
if len(v) > 0 && v[0:1] == ";" {
|
|
||||||
isnote = true //首字母是;时,代表注释
|
|
||||||
}
|
|
||||||
for k, v2 := range v {
|
|
||||||
if k == 0 {
|
|
||||||
if v2 == '[' {
|
|
||||||
isseg = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v2 == '=' && (!istrans && !isnote && !isequal) {
|
|
||||||
isequal = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v2 == ']' && (!istrans && !isnote) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v2 == '#' && (!istrans && !isnote) {
|
|
||||||
isnote = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v2 == '\\' && (!istrans && !isnote) {
|
|
||||||
istrans = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if istrans {
|
|
||||||
istrans = false
|
|
||||||
}
|
|
||||||
if !isnote && (!isequal) {
|
|
||||||
tmp1 = append(tmp1, v2)
|
|
||||||
} else if !isnote && isequal {
|
|
||||||
tmp2 = append(tmp2, v2)
|
|
||||||
} else if isnote {
|
|
||||||
note = append(note, v2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isseg {
|
|
||||||
this.Data = append(this.Data, newseg)
|
|
||||||
newseg.nodeid = nodeint
|
|
||||||
//newseg.cmap = make(map[string]int)
|
|
||||||
newseg.cmap = nodemap
|
|
||||||
nodemap = make(map[string]int)
|
|
||||||
newseg = new(CfgSegment)
|
|
||||||
//newseg.InsertNode = []*CfgNode{}
|
|
||||||
newseg.Name = strings.TrimSpace(string(tmp1))
|
|
||||||
if isnote {
|
|
||||||
newseg.Comment = strings.TrimSpace(string(note))
|
|
||||||
}
|
|
||||||
this.segid++
|
|
||||||
this.segmap[newseg.Name] = this.segid
|
|
||||||
nodeint = 0
|
|
||||||
lastiseg = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if isequal {
|
|
||||||
newnode = new(CfgNode)
|
|
||||||
newnode.Key = strings.TrimSpace(string(tmp1))
|
|
||||||
newnode.Value = strings.TrimSpace(string(tmp2))
|
|
||||||
if isnote {
|
|
||||||
newnode.Comment = strings.TrimSpace(string(note))
|
|
||||||
}
|
|
||||||
newseg.Node = append(newseg.Node, newnode)
|
|
||||||
nodemap[newnode.Key] = nodeint
|
|
||||||
nodeint++
|
|
||||||
lastiseg = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if isnote {
|
|
||||||
comment := strings.TrimSpace(string(note))
|
|
||||||
if lastiseg {
|
|
||||||
newseg.Comment += "\n" + comment
|
|
||||||
} else {
|
|
||||||
newnode.Comment += "\n" + comment
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
newseg.nodeid = nodeint
|
|
||||||
//newseg.cmap = make(map[string]int)
|
|
||||||
newseg.cmap = nodemap
|
|
||||||
this.Data = append(this.Data, newseg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal 输出结果到结构体中
|
|
||||||
func (cfg *StarCfg) Unmarshal(ins interface{}) error {
|
|
||||||
var structSet func(t reflect.Type, v reflect.Value) error
|
|
||||||
t := reflect.TypeOf(ins)
|
|
||||||
v := reflect.ValueOf(ins).Elem()
|
|
||||||
if v.Kind() != reflect.Struct {
|
|
||||||
return errors.New("Not a Struct")
|
|
||||||
}
|
|
||||||
if t.Kind() != reflect.Ptr || !v.CanSet() {
|
|
||||||
return errors.New("Cannot Write!")
|
|
||||||
}
|
|
||||||
t = t.Elem()
|
|
||||||
structSet = func(t reflect.Type, v reflect.Value) error {
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
tp := t.Field(i)
|
|
||||||
vl := v.Field(i)
|
|
||||||
if !vl.CanSet() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if vl.Type().Kind() == reflect.Struct {
|
|
||||||
structSet(vl.Type(), vl)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seg := tp.Tag.Get("seg")
|
|
||||||
key := tp.Tag.Get("key")
|
|
||||||
if seg == "" || key == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := cfg.segmap[seg]; !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
segs := cfg.Data[cfg.segmap[seg]]
|
|
||||||
if segs.Get(key) == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch vl.Kind() {
|
|
||||||
case reflect.String:
|
|
||||||
vl.SetString(segs.Get(key))
|
|
||||||
case reflect.Int, reflect.Int32, reflect.Int64:
|
|
||||||
vl.SetInt(segs.Int64(key))
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
vl.SetFloat(segs.Float64(key))
|
|
||||||
case reflect.Bool:
|
|
||||||
vl.SetBool(segs.Bool(key))
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
vl.SetUint(uint64(segs.Int64(key)))
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return structSet(t, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal 输出结果到结构体中
|
|
||||||
func (cfg *StarCfg) Marshal(ins interface{}) ([]byte, error) {
|
|
||||||
var structSet func(t reflect.Type, v reflect.Value)
|
|
||||||
t := reflect.TypeOf(ins)
|
|
||||||
v := reflect.ValueOf(ins)
|
|
||||||
if v.Kind() != reflect.Struct {
|
|
||||||
return nil, errors.New("Not a Struct")
|
|
||||||
}
|
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
structSet = func(t reflect.Type, v reflect.Value) {
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
var seg, key, comment string = "", "", ""
|
|
||||||
tp := t.Field(i)
|
|
||||||
vl := v.Field(i)
|
|
||||||
if vl.Type().Kind() == reflect.Struct {
|
|
||||||
structSet(vl.Type(), vl)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seg = tp.Tag.Get("seg")
|
|
||||||
key = tp.Tag.Get("key")
|
|
||||||
comment = tp.Tag.Get("comment")
|
|
||||||
if seg == "" || key == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := cfg.segmap[seg]; !ok {
|
|
||||||
cfg.AddSeg(seg)
|
|
||||||
}
|
|
||||||
cfg.Seg(seg).Set(key, fmt.Sprint(vl), comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
structSet(t, v)
|
|
||||||
return cfg.Build(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCfg) Seg(name string) *CfgSegment {
|
|
||||||
if _, ok := this.segmap[name]; !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
seg := this.Data[this.segmap[name]]
|
|
||||||
return seg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *StarCfg) AddSeg(name string) *CfgSegment {
|
|
||||||
if _, ok := cfg.segmap[name]; !ok {
|
|
||||||
newseg := new(CfgSegment)
|
|
||||||
newseg.Name = name
|
|
||||||
newseg.cmap = make(map[string]int)
|
|
||||||
cfg.Data = append(cfg.Data, newseg)
|
|
||||||
cfg.segid++
|
|
||||||
if cfg.segmap == nil {
|
|
||||||
cfg.segid = 0
|
|
||||||
cfg.segmap = make(map[string]int)
|
|
||||||
}
|
|
||||||
cfg.segmap[newseg.Name] = cfg.segid
|
|
||||||
return newseg
|
|
||||||
}
|
|
||||||
seg := cfg.Data[cfg.segmap[name]]
|
|
||||||
return seg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *StarCfg) DeleteSeg(name string) error {
|
|
||||||
if _, ok := cfg.segmap[name]; !ok {
|
|
||||||
return errors.New("Seg Not Exists")
|
|
||||||
}
|
|
||||||
cfg.Data[cfg.segmap[name]] = nil
|
|
||||||
delete(cfg.segmap, name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCfg) Build() []byte {
|
|
||||||
var res, comm string
|
|
||||||
for _, v := range this.Data {
|
|
||||||
comm = ""
|
|
||||||
if v == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v.Name != "unnamed" {
|
|
||||||
res += `[ ` + this.repkv(v.Name) + ` ]`
|
|
||||||
}
|
|
||||||
if v.Comment != "" {
|
|
||||||
comm = strings.Replace(v.Comment, "\n", "\n#", -1)
|
|
||||||
if comm[0:1] != "\n" {
|
|
||||||
comm = " #" + comm
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
res += comm + "\n"
|
|
||||||
for _, v2 := range v.Node {
|
|
||||||
comm = ""
|
|
||||||
if v2 == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
res += this.repkv(v2.Key) + " = " + this.repkv(v2.Value)
|
|
||||||
if v2.Comment != "" {
|
|
||||||
comm = strings.Replace(v2.Comment, "\n", "\n#", -1)
|
|
||||||
if comm[0:1] != "\n" {
|
|
||||||
comm = " #" + comm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res += comm + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return []byte(strings.TrimSpace(res))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StarCfg) repkv(value string) string {
|
|
||||||
value = strings.Replace(value, `\`, `\\`, -1)
|
|
||||||
value = strings.Replace(value, `#`, `\#`, -1)
|
|
||||||
//value = strings.Replace(value, `=`, `\=`, -1)
|
|
||||||
value = strings.Replace(value, `[`, `\[`, -1)
|
|
||||||
value = strings.Replace(value, `]`, `\]`, -1)
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) GetComment(key string) string {
|
|
||||||
if v, ok := this.cmap[key]; !ok {
|
|
||||||
return ""
|
|
||||||
} else {
|
|
||||||
return this.Node[v].Comment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetComment(key, comment string) error {
|
|
||||||
if v, ok := this.cmap[key]; !ok {
|
|
||||||
return errors.New("Key Not Exists")
|
|
||||||
} else {
|
|
||||||
this.Node[v].Comment = comment
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Exist(key string) bool {
|
|
||||||
if _, ok := this.cmap[key]; !ok {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Get(key string) string {
|
|
||||||
if v, ok := this.cmap[key]; !ok {
|
|
||||||
return ""
|
|
||||||
} else {
|
|
||||||
return this.Node[v].Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Int(key string) int {
|
|
||||||
val := this.Get(key)
|
|
||||||
if val == "" {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
res, _ := strconv.Atoi(val)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Int64(key string) int64 {
|
|
||||||
val := this.Get(key)
|
|
||||||
if val == "" {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
res, _ := strconv.ParseInt(val, 10, 64)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Int32(key string) int32 {
|
|
||||||
val := this.Get(key)
|
|
||||||
if val == "" {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
res, _ := strconv.ParseInt(val, 10, 32)
|
|
||||||
return int32(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Float64(key string) float64 {
|
|
||||||
val := this.Get(key)
|
|
||||||
if val == "" {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
res, _ := strconv.ParseFloat(val, 64)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Float32(key string) float32 {
|
|
||||||
val := this.Get(key)
|
|
||||||
if val == "" {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
res, _ := strconv.ParseFloat(val, 32)
|
|
||||||
return float32(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Bool(key string) bool {
|
|
||||||
val := this.Get(key)
|
|
||||||
if val == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
res, _ := strconv.ParseBool(val)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetBool(key string, value bool, comment string) error {
|
|
||||||
res := strconv.FormatBool(value)
|
|
||||||
return this.Set(key, res, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetFloat64(key string, prec int, value float64, comment string) error {
|
|
||||||
res := strconv.FormatFloat(value, 'f', prec, 64)
|
|
||||||
return this.Set(key, res, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetFloat32(key string, prec int, value float32, comment string) error {
|
|
||||||
res := strconv.FormatFloat(float64(value), 'f', prec, 32)
|
|
||||||
return this.Set(key, res, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetInt64(key string, value int64, comment string) error {
|
|
||||||
res := strconv.FormatInt(value, 10)
|
|
||||||
return this.Set(key, res, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetInt32(key string, value int32, comment string) error {
|
|
||||||
res := strconv.FormatInt(int64(value), 10)
|
|
||||||
return this.Set(key, res, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) SetInt(key string, value int, comment string) error {
|
|
||||||
res := strconv.Itoa(value)
|
|
||||||
return this.Set(key, res, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Set(key, value, comment string) error {
|
|
||||||
if v, ok := this.cmap[key]; !ok {
|
|
||||||
node := new(CfgNode)
|
|
||||||
node.Key = key
|
|
||||||
node.Value = value
|
|
||||||
node.Comment = comment
|
|
||||||
this.Node = append(this.Node, node)
|
|
||||||
this.cmap[key] = this.nodeid
|
|
||||||
this.nodeid++
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
this.Node[v].Value = value
|
|
||||||
if comment != "" {
|
|
||||||
this.Node[v].Comment = comment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *CfgSegment) Delete(key string) error {
|
|
||||||
if v, ok := this.cmap[key]; !ok {
|
|
||||||
return errors.New("Key not exists!")
|
|
||||||
} else {
|
|
||||||
this.Node[v] = nil
|
|
||||||
delete(this.cmap, key)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
89
ini_test.go
89
ini_test.go
@ -1,89 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_CfgParse(t *testing.T) {
|
|
||||||
data := `#lalala
|
|
||||||
ok =true\# #ok
|
|
||||||
[happy] #ok
|
|
||||||
#kkk
|
|
||||||
me = \=tru
|
|
||||||
sa = p\\k
|
|
||||||
migrate = ok #oooo
|
|
||||||
[siki]
|
|
||||||
sakurs = ssss #[ossk]`
|
|
||||||
//data, _ := ioutil.ReadFile(`c:\Users\Starainrt\Desktop\postgresql.conf`)
|
|
||||||
ini := new(StarCfg)
|
|
||||||
ini.Parse([]byte(data))
|
|
||||||
ini.Seg("happy").SetInt64("sakura", 986787, "")
|
|
||||||
fmt.Println(string(ini.Build()))
|
|
||||||
}
|
|
||||||
|
|
||||||
type Ntest struct {
|
|
||||||
N string `seg:"happy" key:"me"`
|
|
||||||
}
|
|
||||||
type Testsss struct {
|
|
||||||
Okk string `seg:"unnamed" key:"ok"`
|
|
||||||
Migrate string `seg:"happy" key:"migrate" comment:"whnb"`
|
|
||||||
Ntest
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_CfgParseStruct(t *testing.T) {
|
|
||||||
data := `#lalala
|
|
||||||
ok =true\# #ok
|
|
||||||
[happy] #ok
|
|
||||||
#kkk
|
|
||||||
me = \=tru
|
|
||||||
sa = p\\k
|
|
||||||
migrate = ok #oooo
|
|
||||||
[siki]
|
|
||||||
sakurs = ssss #[ossk]`
|
|
||||||
//data, _ := ioutil.ReadFile(`c:\Users\Starainrt\Desktop\postgresql.conf`)
|
|
||||||
okk := Testsss{}
|
|
||||||
ini := new(StarCfg)
|
|
||||||
ini.Parse([]byte(data))
|
|
||||||
//fmt.Println(ini.Seg("happy").Get("migrate"))
|
|
||||||
fmt.Println(ini.Unmarshal(&okk))
|
|
||||||
fmt.Println(okk)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_DeleteAdd(t *testing.T) {
|
|
||||||
data := `[A]
|
|
||||||
a=1
|
|
||||||
b=2
|
|
||||||
c=3
|
|
||||||
[B]
|
|
||||||
a=1
|
|
||||||
b=2
|
|
||||||
c=3
|
|
||||||
[C]
|
|
||||||
a=1
|
|
||||||
b=2
|
|
||||||
c=3
|
|
||||||
`
|
|
||||||
ini := new(StarCfg)
|
|
||||||
ini.Parse([]byte(data))
|
|
||||||
fmt.Println(ini.Seg("A").Int("a"))
|
|
||||||
fmt.Println(ini.Seg("A").Int("b"))
|
|
||||||
fmt.Println(ini.Seg("B").Int("c"))
|
|
||||||
fmt.Println("-----------------------")
|
|
||||||
ini.Seg("A").Set("d", "4", "")
|
|
||||||
ini.DeleteSeg("B")
|
|
||||||
ini.AddSeg("D")
|
|
||||||
ini.AddSeg("E").SetInt("a", 1, "")
|
|
||||||
ini.Seg("C").Delete("a")
|
|
||||||
fmt.Println(string(ini.Build()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_Marshal(t *testing.T) {
|
|
||||||
var a Testsss
|
|
||||||
a.Migrate = "1"
|
|
||||||
a.N = "2"
|
|
||||||
a.Okk = "okkkkk"
|
|
||||||
ini := StarCfg{}
|
|
||||||
data, err := ini.Marshal(a)
|
|
||||||
fmt.Println(string(data), err)
|
|
||||||
}
|
|
284
net.go
284
net.go
@ -1,284 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
//SecretKey 通信加密Key,不应当被修改
|
|
||||||
const SecretKey string = "1996victorique1127B612BTXL"
|
|
||||||
|
|
||||||
// 识别头
|
|
||||||
var header = []byte{11, 27, 19, 96, 12, 25, 02, 20}
|
|
||||||
|
|
||||||
// MsgQueue 为基本的信息单位
|
|
||||||
type MsgQueue struct {
|
|
||||||
ID uint16
|
|
||||||
Msg []byte
|
|
||||||
Conn interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StarQueue 为流数据中的消息队列分发
|
|
||||||
type StarQueue struct {
|
|
||||||
Encode bool
|
|
||||||
Reserve uint16
|
|
||||||
Msgid uint16
|
|
||||||
MsgPool []MsgQueue
|
|
||||||
UnFinMsg sync.Map
|
|
||||||
LastID int //= -1
|
|
||||||
ctx context.Context
|
|
||||||
cancel context.CancelFunc
|
|
||||||
duration time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewQueue 建立一个新消息队列
|
|
||||||
func NewQueue() *StarQueue {
|
|
||||||
var que StarQueue
|
|
||||||
que.Encode = true
|
|
||||||
que.ctx, que.cancel = context.WithCancel(context.Background())
|
|
||||||
que.duration = 0
|
|
||||||
return &que
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32ToByte 4位uint32转byte
|
|
||||||
func Uint32ToByte(src uint32) []byte {
|
|
||||||
res := make([]byte, 4)
|
|
||||||
res[3] = uint8(src)
|
|
||||||
res[2] = uint8(src >> 8)
|
|
||||||
res[1] = uint8(src >> 16)
|
|
||||||
res[0] = uint8(src >> 24)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByteToUint32 byte转4位uint32
|
|
||||||
func ByteToUint32(src []byte) uint32 {
|
|
||||||
var res uint32
|
|
||||||
buffer := bytes.NewBuffer(src)
|
|
||||||
binary.Read(buffer, binary.BigEndian, &res)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16ToByte 2位uint16转byte
|
|
||||||
func Uint16ToByte(src uint16) []byte {
|
|
||||||
res := make([]byte, 2)
|
|
||||||
res[1] = uint8(src)
|
|
||||||
res[0] = uint8(src >> 8)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByteToUint16 用于byte转uint16
|
|
||||||
func ByteToUint16(src []byte) uint16 {
|
|
||||||
var res uint16
|
|
||||||
buffer := bytes.NewBuffer(src)
|
|
||||||
binary.Read(buffer, binary.BigEndian, &res)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildMessage 生成编码后的信息用于发送
|
|
||||||
func (que *StarQueue) BuildMessage(src []byte) []byte {
|
|
||||||
var buff bytes.Buffer
|
|
||||||
que.Msgid++
|
|
||||||
if que.Encode {
|
|
||||||
cryptos := new(StarCrypto)
|
|
||||||
src = cryptos.VicqueEncodeV1(src, SecretKey)
|
|
||||||
}
|
|
||||||
length := uint32(len(src))
|
|
||||||
buff.Write(header)
|
|
||||||
buff.Write(Uint32ToByte(length))
|
|
||||||
buff.Write(Uint16ToByte(que.Msgid))
|
|
||||||
buff.Write(src)
|
|
||||||
return buff.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
type unFinMsg struct {
|
|
||||||
ID uint16
|
|
||||||
LengthRecv uint32
|
|
||||||
// HeaderMsg 信息头,应当为14位:8位识别码+4位长度码+2位id
|
|
||||||
HeaderMsg []byte
|
|
||||||
RecvMsg []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseMessage 用于解析啊收到的msg信息
|
|
||||||
func (que *StarQueue) ParseMessage(msg []byte, conn interface{}) error {
|
|
||||||
tmp, ok := que.UnFinMsg.Load(conn)
|
|
||||||
cryptos := new(StarCrypto)
|
|
||||||
if ok { //存在未完成的信息
|
|
||||||
lastMsg := tmp.(*unFinMsg)
|
|
||||||
headerLen := len(lastMsg.HeaderMsg)
|
|
||||||
if headerLen < 14 { //未完成头标题
|
|
||||||
//传输的数据不能填充header头
|
|
||||||
if len(msg) < 14-headerLen {
|
|
||||||
//加入header头并退出
|
|
||||||
lastMsg.HeaderMsg = bytesMerge(lastMsg.HeaderMsg, msg)
|
|
||||||
que.UnFinMsg.Store(conn, lastMsg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
//获取14字节完整的header
|
|
||||||
header := msg[0 : 14-headerLen]
|
|
||||||
lastMsg.HeaderMsg = bytesMerge(lastMsg.HeaderMsg, header)
|
|
||||||
//检查收到的header是否为认证header
|
|
||||||
//若不是,丢弃并重新来过
|
|
||||||
if !checkHeader(lastMsg.HeaderMsg[0:8]) {
|
|
||||||
que.UnFinMsg.Delete(conn)
|
|
||||||
if len(msg) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return que.ParseMessage(msg, conn)
|
|
||||||
}
|
|
||||||
//获得本数据包长度
|
|
||||||
lastMsg.LengthRecv = ByteToUint32(lastMsg.HeaderMsg[8:12])
|
|
||||||
//获得本数据包ID
|
|
||||||
lastMsg.ID = ByteToUint16(lastMsg.HeaderMsg[12:14])
|
|
||||||
//存入列表
|
|
||||||
que.UnFinMsg.Store(conn, lastMsg)
|
|
||||||
msg = msg[14-headerLen:]
|
|
||||||
if uint32(len(msg)) < lastMsg.LengthRecv {
|
|
||||||
lastMsg.RecvMsg = msg
|
|
||||||
que.UnFinMsg.Store(conn, lastMsg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if uint32(len(msg)) >= lastMsg.LengthRecv {
|
|
||||||
lastMsg.RecvMsg = msg[0:lastMsg.LengthRecv]
|
|
||||||
if que.Encode {
|
|
||||||
lastMsg.RecvMsg = cryptos.VicqueDecodeV1(lastMsg.RecvMsg, SecretKey)
|
|
||||||
}
|
|
||||||
msg = msg[lastMsg.LengthRecv:]
|
|
||||||
stroeMsg := MsgQueue{
|
|
||||||
ID: lastMsg.ID,
|
|
||||||
Msg: lastMsg.RecvMsg,
|
|
||||||
Conn: conn,
|
|
||||||
}
|
|
||||||
que.MsgPool = append(que.MsgPool, stroeMsg)
|
|
||||||
que.UnFinMsg.Delete(conn)
|
|
||||||
return que.ParseMessage(msg, conn)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lastID := int(lastMsg.LengthRecv) - len(lastMsg.RecvMsg)
|
|
||||||
if lastID < 0 {
|
|
||||||
que.UnFinMsg.Delete(conn)
|
|
||||||
return que.ParseMessage(msg, conn)
|
|
||||||
}
|
|
||||||
if len(msg) >= lastID {
|
|
||||||
lastMsg.RecvMsg = bytesMerge(lastMsg.RecvMsg, msg[0:lastID])
|
|
||||||
if que.Encode {
|
|
||||||
lastMsg.RecvMsg = cryptos.VicqueDecodeV1(lastMsg.RecvMsg, SecretKey)
|
|
||||||
}
|
|
||||||
stroeMsg := MsgQueue{
|
|
||||||
ID: lastMsg.ID,
|
|
||||||
Msg: lastMsg.RecvMsg,
|
|
||||||
Conn: conn,
|
|
||||||
}
|
|
||||||
que.MsgPool = append(que.MsgPool, stroeMsg)
|
|
||||||
que.UnFinMsg.Delete(conn)
|
|
||||||
if len(msg) == lastID {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
msg = msg[lastID:]
|
|
||||||
return que.ParseMessage(msg, conn)
|
|
||||||
}
|
|
||||||
lastMsg.RecvMsg = bytesMerge(lastMsg.RecvMsg, msg)
|
|
||||||
que.UnFinMsg.Store(conn, lastMsg)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(msg) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var start int
|
|
||||||
if start = searchHeader(msg); start == -1 {
|
|
||||||
return errors.New("data format error")
|
|
||||||
}
|
|
||||||
msg = msg[start:]
|
|
||||||
lastMsg := unFinMsg{}
|
|
||||||
que.UnFinMsg.Store(conn, &lastMsg)
|
|
||||||
return que.ParseMessage(msg, conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkHeader(msg []byte) bool {
|
|
||||||
if len(msg) != 8 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for k, v := range msg {
|
|
||||||
if v != header[k] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func searchHeader(msg []byte) int {
|
|
||||||
if len(msg) < 8 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
for k, v := range msg {
|
|
||||||
find := 0
|
|
||||||
if v == header[0] {
|
|
||||||
for k2, v2 := range header {
|
|
||||||
if msg[k+k2] == v2 {
|
|
||||||
find++
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if find == 8 {
|
|
||||||
return k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func bytesMerge(src ...[]byte) []byte {
|
|
||||||
var buff bytes.Buffer
|
|
||||||
for _, v := range src {
|
|
||||||
buff.Write(v)
|
|
||||||
}
|
|
||||||
return buff.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore 获取收到的信息
|
|
||||||
func (que *StarQueue) Restore(n int) ([]MsgQueue, error) {
|
|
||||||
var res []MsgQueue
|
|
||||||
dura := time.Duration(0)
|
|
||||||
for len(que.MsgPool) < n {
|
|
||||||
select {
|
|
||||||
case <-que.ctx.Done():
|
|
||||||
return res, errors.New("Stoped By External Function Call")
|
|
||||||
default:
|
|
||||||
time.Sleep(time.Millisecond * 20)
|
|
||||||
dura = time.Millisecond*20 + dura
|
|
||||||
if que.duration != 0 && dura > que.duration {
|
|
||||||
return res, errors.New("Time Exceed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(que.MsgPool) < n {
|
|
||||||
return res, errors.New("Result Not Enough")
|
|
||||||
}
|
|
||||||
res = que.MsgPool[0:n]
|
|
||||||
que.MsgPool = que.MsgPool[n:]
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RestoreOne 获取收到的一个信息
|
|
||||||
func (que *StarQueue) RestoreOne() (MsgQueue, error) {
|
|
||||||
data, err := que.Restore(1)
|
|
||||||
if len(data) == 1 {
|
|
||||||
return data[0], err
|
|
||||||
}
|
|
||||||
return MsgQueue{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop 立即停止Restore
|
|
||||||
func (que *StarQueue) Stop() {
|
|
||||||
que.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// RestoreDuration Restore最大超时时间
|
|
||||||
func (que *StarQueue) RestoreDuration(tm time.Duration) {
|
|
||||||
que.duration = tm
|
|
||||||
}
|
|
184
net_test.go
184
net_test.go
@ -1,184 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_oldddd(t *testing.T) {
|
|
||||||
a := []int{}
|
|
||||||
a = append(a, 1)
|
|
||||||
a = append(a, 2)
|
|
||||||
a = append(a, 3)
|
|
||||||
fmt.Println(a)
|
|
||||||
a = a[3:]
|
|
||||||
fmt.Println(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_binary(t *testing.T) {
|
|
||||||
bytes := Uint16ToByte(65512)
|
|
||||||
fmt.Println(bytes)
|
|
||||||
fmt.Println(ByteToUint16(bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_test(t *testing.T) {
|
|
||||||
que := NewQueue()
|
|
||||||
okk := que.BuildMessage([]byte(`
|
|
||||||
with
|
|
||||||
all_values as (
|
|
||||||
(select V.ID,
|
|
||||||
V.OBJID,
|
|
||||||
V.TITLE,
|
|
||||||
V.CONTENT,
|
|
||||||
V.URL,
|
|
||||||
V.URL_TYPE,
|
|
||||||
V.STATUS,
|
|
||||||
V.SEARCH_TIMES,
|
|
||||||
V.UPDATE_TIMES
|
|
||||||
from SPMS_SEARCH_VIEW V
|
|
||||||
)
|
|
||||||
|
|
||||||
),
|
|
||||||
in_values as (
|
|
||||||
select T1.*
|
|
||||||
from SPMS_SEARCH_DATASET T1,
|
|
||||||
(select V.ID,
|
|
||||||
V.OBJID,
|
|
||||||
V.TITLE,
|
|
||||||
V.CONTENT,
|
|
||||||
V.URL,
|
|
||||||
V.URL_TYPE,
|
|
||||||
V.STATUS,
|
|
||||||
V.SEARCH_TIMES,
|
|
||||||
V.UPDATE_TIMES
|
|
||||||
from SPMS_SEARCH_VIEW V
|
|
||||||
) T
|
|
||||||
where T.OBJID = T1.OBJID
|
|
||||||
|
|
||||||
),
|
|
||||||
upsert as (
|
|
||||||
update SPMS_SEARCH_DATASET as T1
|
|
||||||
set
|
|
||||||
ID = T.ID,
|
|
||||||
TITLE = T.TITLE,
|
|
||||||
CONTENT = T.CONTENT,
|
|
||||||
URL = T.URL,
|
|
||||||
URL_TYPE = T.URL_TYPE,
|
|
||||||
STATUS = T.STATUS,
|
|
||||||
SEARCH_TIMES = T.SEARCH_TIMES,
|
|
||||||
UPDATE_TIMES = TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'),
|
|
||||||
SYNC_TIMES = V_CUR_TIME
|
|
||||||
from all_values T
|
|
||||||
where T.OBJID = T1.OBJID and TO_DATE(T1.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss') \u003c TO_DATE(TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), 'yyyy-MM-dd hh24:mi:ss')
|
|
||||||
)
|
|
||||||
insert into SPMS_SEARCH_DATASET(ID, OBJID, TITLE, CONTENT, URL, URL_TYPE, STATUS, SEARCH_TIMES, UPDATE_TIMES, SYNC_TIMES)
|
|
||||||
select T.ID,
|
|
||||||
T.OBJID,
|
|
||||||
T.TITLE,
|
|
||||||
T.CONTENT,
|
|
||||||
T.URL,
|
|
||||||
T.URL_TYPE,
|
|
||||||
T.STATUS,
|
|
||||||
T.SEARCH_TIMES,
|
|
||||||
TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'),
|
|
||||||
V_CUR_TIME
|
|
||||||
from (select V.ID,
|
|
||||||
V.OBJID,
|
|
||||||
V.TITLE,
|
|
||||||
V.CONTENT,
|
|
||||||
V.URL,
|
|
||||||
V.URL_TYPE,
|
|
||||||
V.STATUS,
|
|
||||||
V.SEARCH_TIMES,
|
|
||||||
V.UPDATE_TIMES
|
|
||||||
from SPMS_SEARCH_VIEW V
|
|
||||||
) T
|
|
||||||
where not exists(select 1
|
|
||||||
from in_values T1
|
|
||||||
where T.OBJID = T1.OBJID
|
|
||||||
)
|
|
||||||
with
|
|
||||||
all_values as (
|
|
||||||
(select V.ID,
|
|
||||||
V.OBJID,
|
|
||||||
V.TITLE,
|
|
||||||
V.CONTENT,
|
|
||||||
V.URL,
|
|
||||||
V.URL_TYPE,
|
|
||||||
V.STATUS,
|
|
||||||
V.SEARCH_TIMES,
|
|
||||||
V.UPDATE_TIMES
|
|
||||||
from SPMS_SEARCH_VIEW V
|
|
||||||
)
|
|
||||||
|
|
||||||
),
|
|
||||||
in_values as (
|
|
||||||
select T1.*
|
|
||||||
from SPMS_SEARCH_DATASET T1,
|
|
||||||
(select V.ID,
|
|
||||||
V.OBJID,
|
|
||||||
V.TITLE,
|
|
||||||
V.CONTENT,
|
|
||||||
V.URL,
|
|
||||||
V.URL_TYPE,
|
|
||||||
V.STATUS,
|
|
||||||
V.SEARCH_TIMES,
|
|
||||||
V.UPDATE_TIMES
|
|
||||||
from SPMS_SEARCH_VIEW V
|
|
||||||
) T
|
|
||||||
where T.OBJID = T1.OBJID
|
|
||||||
|
|
||||||
),
|
|
||||||
upsert as (
|
|
||||||
update SPMS_SEARCH_DATASET as T1
|
|
||||||
set
|
|
||||||
ID = T.ID,
|
|
||||||
TITLE = T.TITLE,
|
|
||||||
CONTENT = T.CONTENT,
|
|
||||||
URL = T.URL,
|
|
||||||
URL_TYPE = T.URL_TYPE,
|
|
||||||
STATUS = T.STATUS,
|
|
||||||
SEARCH_TIMES = T.SEARCH_TIMES,
|
|
||||||
UPDATE_TIMES = TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'),
|
|
||||||
SYNC_TIMES = V_CUR_TIME
|
|
||||||
from all_values T
|
|
||||||
where T.OBJID = T1.OBJID and TO_DATE(T1.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss') \u003c TO_DATE(TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'), 'yyyy-MM-dd hh24:mi:ss')
|
|
||||||
)
|
|
||||||
insert into SPMS_SEARCH_DATASET(ID, OBJID, TITLE, CONTENT, URL, URL_TYPE, STATUS, SEARCH_TIMES, UPDATE_TIMES, SYNC_TIMES)
|
|
||||||
select T.ID,
|
|
||||||
T.OBJID,
|
|
||||||
T.TITLE,
|
|
||||||
T.CONTENT,
|
|
||||||
T.URL,
|
|
||||||
T.URL_TYPE,
|
|
||||||
T.STATUS,
|
|
||||||
T.SEARCH_TIMES,
|
|
||||||
TO_CHAR(T.UPDATE_TIMES, 'yyyy-MM-dd hh24:mi:ss'),
|
|
||||||
V_CUR_TIME
|
|
||||||
from (select V.ID,
|
|
||||||
V.OBJID,
|
|
||||||
V.TITLE,
|
|
||||||
V.CONTENT,
|
|
||||||
V.URL,
|
|
||||||
V.URL_TYPE,
|
|
||||||
V.STATUS,
|
|
||||||
V.SEARCH_TIMES,
|
|
||||||
V.UPDATE_TIMES
|
|
||||||
from SPMS_SEARCH_VIEW V
|
|
||||||
) T
|
|
||||||
where not exists(select 1
|
|
||||||
from in_values T1
|
|
||||||
where T.OBJID = T1.OBJID
|
|
||||||
)
|
|
||||||
`))
|
|
||||||
fmt.Println(string(okk))
|
|
||||||
que.ParseMessage([]byte{'n', 'm', 'b'}, "nbb")
|
|
||||||
// que.ParseMessage([]byte{'n', 23, 24, 4, 45, 6, 56, 56, 2, 3, 1, 2}, "nbb")
|
|
||||||
que.ParseMessage(okk[0:123], "nbb")
|
|
||||||
que.ParseMessage([]byte{}, "nbb")
|
|
||||||
que.ParseMessage([]byte{}, "nbb")
|
|
||||||
que.ParseMessage([]byte{}, "nbb")
|
|
||||||
que.ParseMessage(okk[123:135], "nbb")
|
|
||||||
que.ParseMessage(okk[135:], "nbb")
|
|
||||||
fmt.Println(string(que.MsgPool[0].Msg))
|
|
||||||
}
|
|
7
shell.go
7
shell.go
@ -31,7 +31,10 @@ func NewPipeShell(command string, arg ...string) (*suncli, error) {
|
|||||||
lovecli.counter = 0
|
lovecli.counter = 0
|
||||||
cmd := exec.Command(command, arg...)
|
cmd := exec.Command(command, arg...)
|
||||||
lovecli.cmd = cmd
|
lovecli.cmd = cmd
|
||||||
|
lovecli.infile, err = lovecli.cmd.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return &lovecli, err
|
||||||
|
}
|
||||||
lovecli.outfile, err = lovecli.cmd.StdoutPipe()
|
lovecli.outfile, err = lovecli.cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &lovecli, err
|
return &lovecli, err
|
||||||
@ -116,7 +119,7 @@ func (this suncli) WriteCmd(cmdstr string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *suncli) ExitCode() int {
|
func (this suncli) ExitCode() int {
|
||||||
return this.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
|
return this.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
202
starainrt.go
202
starainrt.go
@ -1,43 +1,23 @@
|
|||||||
package starainrt
|
package starainrt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"bytes"
|
||||||
"fmt"
|
"database/sql"
|
||||||
"io"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var HttpNul, HttpNul2 map[string]string
|
var HttpNul, HttpNul2 map[string]string
|
||||||
var HttpTimeOut int64 = 15
|
var HttpTimeOut int64 = 15
|
||||||
|
var DBRes *sql.DB
|
||||||
|
var DBRows *sql.Rows
|
||||||
var ShellRes, ShellErr string
|
var ShellRes, ShellErr string
|
||||||
var ShellExit bool
|
var ShellExit bool
|
||||||
|
|
||||||
type CircleByteBuffer struct {
|
//Exits返回指定文件夹/文件是否存在
|
||||||
io.Reader
|
|
||||||
io.Writer
|
|
||||||
io.Closer
|
|
||||||
datas []byte
|
|
||||||
|
|
||||||
start int
|
|
||||||
end int
|
|
||||||
size int
|
|
||||||
isClose bool
|
|
||||||
isEnd bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCircleByteBuffer(len int) *CircleByteBuffer {
|
|
||||||
var e = new(CircleByteBuffer)
|
|
||||||
e.datas = make([]byte, len)
|
|
||||||
e.start = 0
|
|
||||||
e.end = 0
|
|
||||||
e.size = len
|
|
||||||
e.isClose = false
|
|
||||||
e.isEnd = false
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exists 返回指定文件夹/文件是否存在
|
|
||||||
func Exists(filepath string) bool {
|
func Exists(filepath string) bool {
|
||||||
_, err := os.Stat(filepath)
|
_, err := os.Stat(filepath)
|
||||||
if err != nil && os.IsNotExist(err) {
|
if err != nil && os.IsNotExist(err) {
|
||||||
@ -66,128 +46,74 @@ func IsFolder(fpath string) bool {
|
|||||||
return s.IsDir()
|
return s.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *CircleByteBuffer) getLen() int {
|
//CurlGet发起一个HTTP GET请求
|
||||||
if e.start == e.end {
|
func CurlGet(url string) (error, []byte) {
|
||||||
return 0
|
err, _, res, _, _ := Curl(url, "", HttpNul, HttpNul2, "GET")
|
||||||
} else if e.start < e.end {
|
return err, res
|
||||||
return e.end - e.start
|
|
||||||
} else {
|
|
||||||
return e.start - e.end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (e *CircleByteBuffer) getFree() int {
|
|
||||||
return e.size - e.getLen()
|
|
||||||
}
|
|
||||||
func (e *CircleByteBuffer) putByte(b byte) error {
|
|
||||||
if e.isClose {
|
|
||||||
return io.EOF
|
|
||||||
}
|
|
||||||
e.datas[e.end] = b
|
|
||||||
var pos = e.end + 1
|
|
||||||
for pos == e.start {
|
|
||||||
if e.isClose {
|
|
||||||
return io.EOF
|
|
||||||
}
|
|
||||||
time.Sleep(time.Microsecond)
|
|
||||||
}
|
|
||||||
if pos == e.size {
|
|
||||||
e.end = 0
|
|
||||||
} else {
|
|
||||||
e.end = pos
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *CircleByteBuffer) getByte() (byte, error) {
|
//CurlPost发起一个基于表单的HTTP Post请求
|
||||||
if e.isClose {
|
func CurlPost(url, postdata string) (error, []byte) {
|
||||||
return 0, io.EOF
|
err, _, res, _, _ := Curl(url, postdata, HttpNul, HttpNul2, "POST")
|
||||||
}
|
return err, res
|
||||||
if e.isEnd && e.getLen() <= 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
if e.getLen() <= 0 {
|
|
||||||
return 0, errors.New("no datas")
|
|
||||||
}
|
|
||||||
var ret = e.datas[e.start]
|
|
||||||
e.start++
|
|
||||||
if e.start == e.size {
|
|
||||||
e.start = 0
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
func (e *CircleByteBuffer) geti(i int) byte {
|
|
||||||
if i >= e.getLen() {
|
|
||||||
panic("out buffer")
|
|
||||||
}
|
|
||||||
var pos = e.start + i
|
|
||||||
if pos >= e.size {
|
|
||||||
pos -= e.size
|
|
||||||
}
|
|
||||||
return e.datas[pos]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func (e*CircleByteBuffer)puts(bts []byte){
|
//HttpNulReset将重置Header和Cookie为空
|
||||||
for i:=0;i<len(bts);i++{
|
func HttpNulReset() {
|
||||||
e.put(bts[i])
|
var tmp map[string]string
|
||||||
|
HttpNul, HttpNul2 = tmp, tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
func Curl(url string, postdata string, header map[string]string, cookie map[string]string, method string) (error, int, []byte, http.Header, []*http.Cookie) {
|
||||||
|
var req *http.Request
|
||||||
|
if method == "" {
|
||||||
|
if len(postdata) != 0 {
|
||||||
|
method = "POST"
|
||||||
|
} else {
|
||||||
|
method = "GET"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (e*CircleByteBuffer)gets(bts []byte)int{
|
BytePostData := []byte(postdata)
|
||||||
if bts==nil {return 0}
|
if postdata == "" || len(postdata) == 0 {
|
||||||
var ret=0
|
req, _ = http.NewRequest(method, url, nil)
|
||||||
for i:=0;i<len(bts);i++{
|
} else {
|
||||||
if e.getLen()<=0{break}
|
req, _ = http.NewRequest(method, url, bytes.NewBuffer(BytePostData))
|
||||||
bts[i]=e.get()
|
|
||||||
ret++
|
|
||||||
}
|
}
|
||||||
return ret
|
|
||||||
}*/
|
if (len(header) == 0 || header == nil) && method == "POST" {
|
||||||
func (e *CircleByteBuffer) Close() error {
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
e.isClose = true
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
func (e *CircleByteBuffer) Read(bts []byte) (int, error) {
|
for k, v := range header {
|
||||||
if e.isClose {
|
req.Header.Set(k, v)
|
||||||
return 0, io.EOF
|
|
||||||
}
|
}
|
||||||
if bts == nil {
|
if len(cookie) != 0 {
|
||||||
return 0, errors.New("bts is nil")
|
for k, v := range cookie {
|
||||||
|
req.AddCookie(&http.Cookie{Name: k, Value: v, HttpOnly: true})
|
||||||
}
|
}
|
||||||
var ret = 0
|
|
||||||
for i := 0; i < len(bts); i++ {
|
}
|
||||||
b, err := e.getByte()
|
client := &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Dial: func(netw, addr string) (net.Conn, error) {
|
||||||
|
deadline := time.Now().Add(time.Duration(HttpTimeOut) * time.Second)
|
||||||
|
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(HttpTimeOut))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
return nil, err
|
||||||
return ret, err
|
|
||||||
}
|
}
|
||||||
return ret, nil
|
c.SetDeadline(deadline)
|
||||||
}
|
return c, nil
|
||||||
bts[i] = b
|
},
|
||||||
ret++
|
}}
|
||||||
}
|
resp, err := client.Do(req)
|
||||||
if e.isClose {
|
var rte []*http.Cookie
|
||||||
return ret, io.EOF
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
func (e *CircleByteBuffer) Write(bts []byte) (int, error) {
|
|
||||||
if e.isClose {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
if bts == nil {
|
|
||||||
e.isEnd = true
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
var ret = 0
|
|
||||||
for i := 0; i < len(bts); i++ {
|
|
||||||
err := e.putByte(bts[i])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Write bts err:", err)
|
return err, 0, []byte(""), req.Header, rte
|
||||||
return ret, err
|
|
||||||
}
|
}
|
||||||
ret++
|
defer resp.Body.Close()
|
||||||
}
|
|
||||||
if e.isClose {
|
statuscode := resp.StatusCode
|
||||||
return ret, io.EOF
|
hea := resp.Header
|
||||||
}
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
return ret, nil
|
return nil, statuscode, body, hea, resp.Cookies()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
161
starshell.go
161
starshell.go
@ -1,161 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StarShell struct {
|
|
||||||
outfile *io.ReadCloser
|
|
||||||
infile *io.WriteCloser
|
|
||||||
errfile *io.ReadCloser
|
|
||||||
cmd *exec.Cmd
|
|
||||||
running bool
|
|
||||||
stopSign context.Context
|
|
||||||
stopFunc context.CancelFunc
|
|
||||||
stdout []byte
|
|
||||||
errout []byte
|
|
||||||
runerr error
|
|
||||||
exitcode int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStarShell(command string, args ...string) (*StarShell, error) {
|
|
||||||
shell := new(StarShell)
|
|
||||||
shell.stopSign, shell.stopFunc = context.WithCancel(context.Background())
|
|
||||||
cmd := exec.CommandContext(shell.stopSign, command, args...)
|
|
||||||
shell.cmd = cmd
|
|
||||||
infile, err := shell.cmd.StdinPipe()
|
|
||||||
if err != nil {
|
|
||||||
return shell, err
|
|
||||||
}
|
|
||||||
shell.infile = &infile
|
|
||||||
errfile, err := shell.cmd.StderrPipe()
|
|
||||||
if err != nil {
|
|
||||||
return shell, err
|
|
||||||
}
|
|
||||||
shell.errfile = &errfile
|
|
||||||
outfile, err := shell.cmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return shell, err
|
|
||||||
}
|
|
||||||
shell.outfile = &outfile
|
|
||||||
shell.runerr = nil
|
|
||||||
shell.exitcode = -999
|
|
||||||
return shell, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) Start() error {
|
|
||||||
if err := starcli.cmd.Start(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
starcli.running = true
|
|
||||||
go func() {
|
|
||||||
err := starcli.cmd.Wait()
|
|
||||||
if err != nil {
|
|
||||||
starcli.runerr = err
|
|
||||||
}
|
|
||||||
starcli.exitcode = starcli.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
|
|
||||||
starcli.running = false
|
|
||||||
}()
|
|
||||||
go starcli.queryResult()
|
|
||||||
go starcli.queryErrResult()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) queryResult() error {
|
|
||||||
for starcli.running {
|
|
||||||
out := make([]byte, 65535)
|
|
||||||
n, err := (*starcli.outfile).Read(out)
|
|
||||||
if n != 0 {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
starcli.stdout = append(starcli.stdout, out[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
starcli.runerr = err
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
time.Sleep(time.Microsecond * 100)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) queryErrResult() error {
|
|
||||||
for starcli.running {
|
|
||||||
out := make([]byte, 65535)
|
|
||||||
n, err := (*starcli.errfile).Read(out)
|
|
||||||
if n != 0 {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
starcli.errout = append(starcli.errout, out[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
starcli.runerr = err
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time.Sleep(time.Microsecond * 100)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) GetResult() (string, error) {
|
|
||||||
np := len(starcli.stdout)
|
|
||||||
res1 := string(starcli.stdout[0:np])
|
|
||||||
starcli.stdout = starcli.stdout[np:]
|
|
||||||
np = len(starcli.errout)
|
|
||||||
res2 := string(starcli.errout[0:np])
|
|
||||||
starcli.errout = starcli.errout[np:]
|
|
||||||
if len(res2) == 0 && starcli.runerr != nil {
|
|
||||||
res2 = starcli.runerr.Error()
|
|
||||||
}
|
|
||||||
if len(res2) == 0 {
|
|
||||||
return res1, nil
|
|
||||||
}
|
|
||||||
return res1, errors.New(res2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) Exec(cmd string, wait int) (string, error) {
|
|
||||||
(*starcli.infile).Write([]byte(cmd + "\n"))
|
|
||||||
time.Sleep(time.Millisecond * time.Duration(wait))
|
|
||||||
return starcli.GetResult()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) WriteCmd(cmdstr string) {
|
|
||||||
(*starcli.infile).Write([]byte(cmdstr + "\n"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) ExitCode() int {
|
|
||||||
return starcli.exitcode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) Kill() {
|
|
||||||
starcli.stopFunc()
|
|
||||||
starcli.running = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) IsRunning() bool {
|
|
||||||
return starcli.running
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) GetPid() int {
|
|
||||||
return starcli.cmd.Process.Pid
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) Signal(sig os.Signal) error {
|
|
||||||
return starcli.cmd.Process.Signal(sig)
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
// +build linux
|
|
||||||
|
|
||||||
package starainrt
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func (starcli *StarShell) SetRunUser(uid, gid uint32) {
|
|
||||||
starcli.cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
Credential: &syscall.Credential{
|
|
||||||
Uid: uid,
|
|
||||||
Gid: gid,
|
|
||||||
},
|
|
||||||
Setsid: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) Release() error {
|
|
||||||
if err := starcli.cmd.Start(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
starcli.cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
Setsid: true,
|
|
||||||
}
|
|
||||||
starcli.cmd.Process.Release()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (starcli *StarShell) SetKeepCaps() error {
|
|
||||||
_, _, err := syscall.RawSyscall(157 /*SYS PRCTL */, 0x8 /*PR SET KEEPCAPS*/, 1, 0)
|
|
||||||
if 0 != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package starainrt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Starshell(t *testing.T) {
|
|
||||||
star, err := NewStarShell("cmd.exe")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
time.Sleep(time.Second * 2)
|
|
||||||
star.WriteCmd("chcp 65001")
|
|
||||||
time.Sleep(time.Second * 2)
|
|
||||||
star.WriteCmd("ping baidu.com -n 10")
|
|
||||||
time.Sleep(time.Second * 12)
|
|
||||||
star.WriteCmd("exit")
|
|
||||||
}()
|
|
||||||
for star.IsRunning() {
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
str, err := star.GetResult()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("error:", err)
|
|
||||||
}
|
|
||||||
fmt.Print(str)
|
|
||||||
}
|
|
||||||
fmt.Println(star.ExitCode())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_Starbash(t *testing.T) {
|
|
||||||
star, err := NewStarShell("bash", "-c", "ping baidu.com -c 10")
|
|
||||||
err = star.Start()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
go func() {
|
|
||||||
time.Sleep(time.Second * 2)
|
|
||||||
star.WriteCmd("chcp 65001")
|
|
||||||
time.Sleep(time.Second * 2)
|
|
||||||
star.WriteCmd("ping baidu.com -n 10")
|
|
||||||
time.Sleep(time.Second * 12)
|
|
||||||
star.WriteCmd("exit")
|
|
||||||
}()
|
|
||||||
*/
|
|
||||||
for star.IsRunning() {
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
str, err := star.GetResult()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("error:", err)
|
|
||||||
}
|
|
||||||
fmt.Print(str)
|
|
||||||
}
|
|
||||||
fmt.Println(star.ExitCode())
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user