commit 9e7cf3e0ec6ec413577ef11ff5f595a6fe42b8d6
parent 70a0e37cfaba67dbb657cf475e6053b95f0cb280
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 6 Sep 2023 08:46:45 +0900
implement newR...() functions
Diffstat:
| M | fcall.go | | | 98 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
| M | stat.go | | | 40 | ++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 118 insertions(+), 20 deletions(-)
diff --git a/fcall.go b/fcall.go
@@ -2,7 +2,6 @@ package lib9p
import (
"fmt"
- "io/fs"
)
type MsgType uint8
@@ -109,7 +108,14 @@ type RVersion struct {
version string
}
-func newRVersion(buf []byte) *RVersion { panic("not implemented") }
+func newRVersion(buf []byte) *RVersion {
+ msg := new(RVersion)
+ msg.tag = gbit16(buf[5:7])
+ msg.mSize = gbit32(buf[7:11])
+ vs := gbit16(buf[11:13])
+ msg.version = string(buf[13:13+vs])
+ return msg
+}
func (msg *RVersion) Size() uint32 { return uint32(4 + 1 + 2 + 4 + 2 + len(msg.version)) }
func (msg *RVersion) Type() MsgType { return Rversion }
func (msg *RVersion) Tag() uint16 { return msg.tag }
@@ -223,14 +229,19 @@ func (msg TAuth) String() string {
type RAuth struct {
tag uint16
- aqid *Qid
+ aqid Qid
}
-func newRAuth(buf []byte) *RAuth { panic("not implemented") }
+func newRAuth(buf []byte) *RAuth {
+ msg := new(RAuth)
+ msg.tag = gbit16(buf[5:7])
+ msg.aqid = unmarshalQid(buf[7:])
+ return msg
+}
func (msg RAuth) Size() uint32 { return 4 + 1 + 2 + 13 }
func (msg RAuth) Type() MsgType { return Rauth }
func (msg RAuth) Tag() uint16 { return msg.tag }
-func (msg RAuth) AQid() *Qid { return msg.aqid }
+func (msg RAuth) AQid() Qid { return msg.aqid }
func (msg RAuth) marshal() []byte {
cur := 0
buf := make([]byte, msg.Size())
@@ -346,7 +357,12 @@ type RAttach struct {
qid Qid
}
-func newRAttach(buf []byte) *RAttach { panic("not implemented") }
+func newRAttach(buf []byte) *RAttach {
+ msg := new(RAttach)
+ msg.tag = gbit16(buf[5:7])
+ msg.qid = unmarshalQid(buf[7:])
+ return msg
+}
func (msg RAttach) Size() uint32 { return 4 + 1 + 2 + 13 }
func (msg RAttach) Type() MsgType { return Rattach }
func (msg RAttach) Tag() uint16 { return msg.tag }
@@ -380,7 +396,13 @@ type RError struct {
ename error
}
-func newRError(buf []byte) *RError { panic("not implemented") }
+func newRError(buf []byte) *RError {
+ msg := new(RError)
+ msg.tag = gbit16(buf[5:7])
+ es := gbit16(buf[7:9])
+ msg.ename = fmt.Errorf("%s", string(buf[9:9+es]))
+ return msg
+}
func (msg *RError) Size() uint32 { return uint32(4 + 1 + 2 + 2 + len(msg.EName())) }
func (msg *RError) Type() MsgType { return Rerror }
func (msg *RError) Tag() uint16 { return msg.tag }
@@ -491,16 +513,30 @@ func (msg *TWalk) String() string {
type RWalk struct {
tag uint16
- qid []*Qid
+ qid []Qid
}
-func newRWalk(buf []byte) *RWalk { panic("not implemented") }
+func newRWalk(buf []byte) *RWalk {
+ msg := new(RWalk)
+ msg.tag = gbit16(buf[5:7])
+ nwqid := int(gbit16(buf[7:9]))
+ msg.qid = make([]Qid, nwqid)
+ cur := 9
+ for i := 0; i < nwqid; i++ {
+ msg.qid[i] = unmarshalQid(buf[cur:cur+13])
+ cur += 13
+ }
+ if int(msg.Size()) != cur {
+ panic("length of buf and cursor position don't match")
+ }
+ return msg
+}
func (msg *RWalk) Size() uint32 {
return uint32(4 + 1 + 2 + 2 + len(msg.Qid())*13)
}
func (msg *RWalk) Type() MsgType { return Rwalk }
func (msg *RWalk) Tag() uint16 { return msg.tag }
-func (msg *RWalk) Qid() []*Qid { return msg.qid }
+func (msg *RWalk) Qid() []Qid { return msg.qid }
func (msg *RWalk) marshal() []byte {
cur := 0
buf := make([]byte, msg.Size())
@@ -590,7 +626,13 @@ type ROpen struct {
iounit uint32
}
-func newROpen(buf []byte) *ROpen { panic("not implemented") }
+func newROpen(buf []byte) *ROpen {
+ msg := new(ROpen)
+ msg.tag = gbit16(buf[5:7])
+ msg.qid = unmarshalQid(buf[7:20])
+ msg.iounit = gbit32(buf[20:24])
+ return msg
+}
func (msg *ROpen) Size() uint32 {
return uint32(4 + 1 + 2 + 13 + 4)
}
@@ -688,7 +730,16 @@ type RRead struct {
data []byte
}
-func newRRead(buf []byte) *RRead { panic("not implemented") }
+func newRRead(buf []byte) *RRead {
+ msg := new(RRead)
+ msg.tag = gbit16(buf[5:7])
+ msg.count = gbit32(buf[7:11])
+ msg.data = make([]byte, msg.count)
+ for i := 0; i < int(msg.count); i++ {
+ msg.data[i] = buf[11+i]
+ }
+ return msg
+}
func (msg *RRead) Size() uint32 {
return uint32(4 + 1 + 2 + 4 + msg.Count())
}
@@ -775,7 +826,11 @@ type RClunk struct {
tag uint16
}
-func newRClunk(buf []byte) *RClunk { panic("not implemented") }
+func newRClunk(buf []byte) *RClunk {
+ msg := new(RClunk)
+ msg.tag = gbit16(buf[5:7])
+ return msg
+}
func (msg *RClunk) Size() uint32 { return 7 }
func (msg *RClunk) Type() MsgType { return Rclunk }
func (msg *RClunk) Tag() uint16 { return msg.tag }
@@ -822,13 +877,17 @@ func (msg *TStat) String() string {
type RStat struct {
tag uint16
- info fs.FileInfo
+ stat *Stat
}
-func newRStat(buf []byte) *RStat { panic("not implemented") }
+func newRStat(buf []byte) *RStat {
+ msg := new(RStat)
+ msg.tag = gbit16(buf[5:7])
+ msg.stat = newStat(buf[9:])
+ return msg
+}
func (msg *RStat) Size() uint32 {
- Stat := msg.info.Sys().(*Stat)
- return uint32(4 + 1 + 2 + 2 + 2 + Stat.size())
+ return uint32(4 + 1 + 2 + 2 + 2 + msg.stat.size())
}
func (msg *RStat) Type() MsgType { return Rstat }
func (msg *RStat) Tag() uint16 { return msg.tag }
@@ -837,9 +896,8 @@ func (msg *RStat) marshal() []byte {
pbit32(buf[0:4], msg.Size())
buf[4] = uint8(Rstat)
pbit16(buf[5:7], msg.Tag())
- Stat := msg.info.Sys().(*Stat)
- fiBuf := Stat.marshal()
+ fiBuf := msg.stat.marshal()
pbit16(buf[7:9], uint16(len(fiBuf)))
for i := 0; i < len(fiBuf); i++ {
buf[9+i] = fiBuf[i]
@@ -848,5 +906,5 @@ func (msg *RStat) marshal() []byte {
}
func (msg *RStat) String() string {
- return fmt.Sprintf("Rstat tag %d Stat %s", msg.Tag(), msg.info.Sys().(*Stat))
+ return fmt.Sprintf("Rstat tag %d Stat %s", msg.Tag(), msg.stat)
}
diff --git a/stat.go b/stat.go
@@ -51,6 +51,46 @@ func StatFromFile(f File) *Stat {
}
}
+func newStat(b []byte) *Stat {
+ stat := new(Stat)
+ cur := 2 // ignore size field
+ stat.Type = gbit16(b[cur:cur+2])
+ cur += 2
+ stat.Dev = gbit32(b[cur:cur+4])
+ cur += 4
+ stat.Qid = unmarshalQid(b[cur:cur+13])
+ cur += 13
+ stat.Mode = FileMode(gbit32(b[cur:cur+4]))
+ cur += 4
+ stat.Atime = gbit32(b[cur:cur+4])
+ cur += 4
+ stat.Mtime = gbit32(b[cur:cur+4])
+ cur += 4
+ stat.Length = int64(gbit64(b[cur:cur+8]))
+ cur += 8
+ nameSize := int(gbit16(b[cur:cur+2]))
+ cur += 2
+ stat.Name = string(b[cur:cur+nameSize])
+ cur += nameSize
+ uidSize := int(gbit16(b[cur:cur+2]))
+ cur += 2
+ stat.Uid = string(b[cur:cur+uidSize])
+ cur += uidSize
+ gidSize := int(gbit16(b[cur:cur+2]))
+ cur += 2
+ stat.Gid = string(b[cur:cur+gidSize])
+ cur += gidSize
+ muidSize := int(gbit16(b[cur:cur+2]))
+ cur += 2
+ stat.Muid = string(b[cur:cur+muidSize])
+ cur += muidSize
+ if cur != len(b) {
+ panic("length and cursor position don't match")
+ }
+
+ return stat
+}
+
func (s *Stat) size() uint16 {
// type + dev + qid + mode + atime + mtime + length
return uint16(2 + 4 + 13 + 4 + 4 + 4 + 8 +