1 Star 1 Fork 0

LineOfSight / resob

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
BsTrstruct_remote.go 9.00 KB
一键复制 编辑 原始数据 按行查看 历史
LineOfSight 提交于 2024-01-11 02:44 . resob_BsTrstruct
// Copyright 2023 @Author:LiuBin(LineOfSight) 1440383523@qq.com. All rights reserved.
// Licensed under the MulanPSL-2.0 License.
package resob
import (
"bufio"
"bytes"
"encoding/binary"
"io"
"log"
"net"
"os"
"sync"
)
type fileops_params struct {
c net.Conn
}
var __global_fileops__ chan *fileops_params
var __global_stop_fileops__ chan struct{}
// key is f.Name()
var __global_name_f_map__ sync.Map
func _groutine_fileops() {
var be bool
for !be {
select {
case d, ok := <-__global_fileops__:
if ok {
r := bufio.NewReader(d.c)
b := make([]byte, 8) //wr
n, e := r.Read(b)
if n != 8 || e != nil {
d.c.Close()
continue
}
wr := int64(binary.BigEndian.Uint32(b))
switch wr {
case WNoRRe, MNoRRe, WRRe, MRRe, ORRe:
b = make([]byte, 4) //filename len
n, e = r.Read(b)
if n != 4 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
fl := int(binary.BigEndian.Uint32(b))
b = make([]byte, fl)
n, e = r.Read(b)
if n != fl || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
fn := string(b)
var f *os.File
if fo, ok := __global_name_f_map__.Load(fn); !ok {
if f, e = os.OpenFile(fn, os.O_CREATE|os.O_RDWR, 0644); e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
__global_name_f_map__.Store(fn, f)
} else {
f = fo.(*os.File)
}
var offset, agosize, pagesz int64
if wr == MRRe || wr == MNoRRe {
b = make([]byte, 8) //offset
n, e = r.Read(b)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
offset = int64(binary.BigEndian.Uint64(b))
}
b = make([]byte, 8) //agosize
n, e = r.Read(b)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
agosize = int64(binary.BigEndian.Uint64(b))
b = make([]byte, 8) //pagesz
n, e = r.Read(b)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
pagesz = int64(binary.BigEndian.Uint64(b))
b = make([]byte, 8) //cs.length
n, e = r.Read(b)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
length := int64(binary.BigEndian.Uint64(b))
if length < agosize && (wr == MRRe || wr == MNoRRe) {
f.Seek(offset, io.SeekStart)
var n1 int64
n1, e = io.CopyN(f, d.c, length)
if n1 != length || e == io.EOF {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
} else {
var sz int64
if agosize == 0 || agosize < length {
if length < pagesz {
sz = pagesz
} else {
sz = length
}
}
offset, e = f.Seek(0, io.SeekEnd)
if e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
_, e = f.Write((__global_nop__)[:sz])
if e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
if wr == WRRe {
f.Seek(offset, io.SeekStart)
var n1 int64
n1, e = io.CopyN(f, d.c, sz)
if n1 != sz || e == io.EOF {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
}
}
buf := __global_write_pool__.Get().(*bytes.Buffer)
buf.Reset()
e = binary.Write(buf, binary.BigEndian, offset)
if e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
ob := make([]byte, 8)
copy(ob, buf.Bytes())
__global_write_pool__.Put(buf)
if wr == MRRe || wr == WRRe || wr == ORRe {
n, e = d.c.Write(ob)
if n != 8 || e != nil {
//only spire offsetis 0
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
}
case RRRe, RhtRRe:
b = make([]byte, 4) //filename len
n, e = r.Read(b)
if n != 4 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
fl := int(binary.BigEndian.Uint32(b))
b = make([]byte, fl)
n, e = r.Read(b)
if n != fl || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
fn := string(b)
var f *os.File
if fo, ok := __global_name_f_map__.Load(fn); !ok {
if f, e = os.OpenFile(fn, os.O_CREATE|os.O_RDWR, 0644); e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
__global_name_f_map__.Store(fn, f)
} else {
f = fo.(*os.File)
}
b = make([]byte, 8) //offset
n, e = r.Read(b)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
offset := int64(binary.BigEndian.Uint64(b))
ht, _ := GetHeadAndTailFromFileOff(offset, f)
if ht == nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
if wr == RRRe {
buf := __global_write_pool__.Get().(*bytes.Buffer)
buf.Reset()
e = binary.Write(buf, binary.BigEndian, ht.length)
if e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
lb := make([]byte, 8)
copy(lb, buf.Bytes())
__global_write_pool__.Put(buf)
n, e = d.c.Write(lb)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
f.Seek(offset, io.SeekStart)
var n64 int64
n64, e = io.CopyN(d.c, f, ht.length)
if n64 != ht.length || e == io.EOF {
d.c.Close()
continue
}
} else {
buf := __global_write_pool__.Get().(*bytes.Buffer)
buf.Reset()
e = binary.Write(buf, binary.BigEndian, NUDECSLEN)
if e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
lb := make([]byte, 8)
copy(lb, buf.Bytes())
__global_write_pool__.Put(buf)
n, e = d.c.Write(lb)
if n != 8 || e != nil {
d.c.Write(make([]byte, 8))
d.c.Close()
continue
}
buf = __global_write_pool__.Get().(*bytes.Buffer)
buf.Reset()
e = ht.ElementsToBytes(buf)
if e != nil {
d.c.Close()
continue
}
cs_bytes := make([]byte, len(buf.Bytes()), cap(buf.Bytes()))
copy(cs_bytes, buf.Bytes())
__global_write_pool__.Put(buf)
n, e = d.c.Write(cs_bytes)
if n != len(cs_bytes) || e != nil {
d.c.Close()
continue
}
}
case DRRe:
b = make([]byte, 4) //filename len
n, e = r.Read(b)
if n != 4 || e != nil {
d.c.Write(make([]byte, 1, 1))
d.c.Close()
continue
}
fl := int(binary.BigEndian.Uint32(b))
b = make([]byte, fl)
n, e = r.Read(b)
if n != fl || e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
fn := string(b)
var f *os.File
if fo, ok := __global_name_f_map__.Load(fn); !ok {
if f, e = os.OpenFile(fn, os.O_CREATE|os.O_RDWR, 0644); e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
__global_name_f_map__.Store(fn, f)
} else {
f = fo.(*os.File)
}
b = make([]byte, 8) //offset
n, e = r.Read(b)
if n != 8 || e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
offset := int64(binary.BigEndian.Uint64(b))
b = make([]byte, 2) //flag
n, e = r.Read(b)
if n != 2 || e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
flag := binary.BigEndian.Uint16(b)
_, e = f.Seek(offset+18, io.SeekStart) //seek to cs.flag
if e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
buf := __global_write_pool__.Get().(*bytes.Buffer)
buf.Reset()
e = binary.Write(buf, binary.BigEndian, flag)
if e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
_, e = f.Write(buf.Bytes())
if e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
__global_write_pool__.Put(buf)
buf = __global_write_pool__.Get().(*bytes.Buffer)
buf.Reset()
e = binary.Write(buf, binary.BigEndian, int8(-1))
if e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
rb := make([]byte, 1)
copy(rb, buf.Bytes())
__global_write_pool__.Put(buf)
n, e = d.c.Write(rb)
if n != 1 || e != nil {
d.c.Write(make([]byte, 1))
d.c.Close()
continue
}
}
}
case <-__global_stop_fileops__:
close(__global_stop_fileops__)
be = !be
}
}
}
// BsTrFileServ starts a remote server for filing a Bstr by channel request in i_BsTrstruct_ffunc.go
func BsTrFileServ(n, ap string) error {
__global_once4initBsTr__.Do(func() {
__global_fileops__ = make(chan *fileops_params, DefaultChanSz)
__global_stop_fileops__ = make(chan struct{})
go _groutine_fileops()
})
l, e := net.Listen(n, ap)
if e != nil {
return e
}
for {
c, e := l.Accept()
if e != nil {
log.Println("Accept failed:", e)
continue
}
__global_fileops__ <- &fileops_params{c}
}
}
Go
1
https://gitee.com/lineofsight/resob.git
git@gitee.com:lineofsight/resob.git
lineofsight
resob
resob
5b7b5e40e6d1

搜索帮助