~rbn/neinp

ref: 062a107b140085acd6c48867e4328fb3f3466a87 neinp/message/create.go -rw-r--r-- 2.8 KiB
062a107bRuben Schuller use custom go.rbn.im import path 1 year, 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package message // import "go.rbn.im/neinp/message"

import (
	"go.rbn.im/neinp/basic"
	"go.rbn.im/neinp/qid"
	"go.rbn.im/neinp/stat"
	"io"
)

/*TCreate asks the file server to create a new file.

The file is to be created in the directory represented by Fid, with the supplied Name.
Write permission is required on the directory. The owner will be implied by the
file systems used. The group is the same as the directories.
Permissions for a file will be set to

	Perm & 0666 | DPerm & 0666

or

	Perm & 0777 | DPerm & 0777

if a directory (DPerm being the permissions of the parent directory).

The created file is opened with Mode, and Fid will represent the new file.
Mode is not checked to fulfill the permissions of Perm.

Directories are created by setting the DirModeDir bit
in Perm.

Names "." and ".." are forbidden.

Fid must not be in use already.

Creating a file with a name already in use, will truncate the existing file.

See also: http://man.cat-v.org/plan_9/5/open
*/
type TCreate struct {
	Fid  uint32
	Name string
	Perm stat.Mode
	Mode OpenMode
}

func (m *TCreate) encode(w io.Writer) (int64, error) {
	n1, err := basic.Uint32Encode(w, m.Fid)
	if err != nil {
		return n1, err
	}

	n2, err := basic.StringEncode(w, m.Name)
	if err != nil {
		return n1 + n2, err
	}

	n3, err := basic.Uint32Encode(w, uint32(m.Perm))
	if err != nil {
		return n1 + n2 + n3, err
	}

	n4, err := basic.Uint8Encode(w, uint8(m.Mode))
	if err != nil {
		return n1 + n2 + n3 + n4, err
	}

	return n1 + n2 + n3 + n4, nil
}

func (m *TCreate) decode(r io.Reader) (int64, error) {
	fid, n1, err := basic.Uint32Decode(r)
	if err != nil {
		return n1, err
	}

	name, n2, err := basic.StringDecode(r)
	if err != nil {
		return n1 + n2, err
	}

	perm, n3, err := basic.Uint32Decode(r)
	if err != nil {
		return n1 + n2 + n3, err
	}

	mod, n4, err := basic.Uint8Decode(r)
	if err != nil {
		return n1 + n2 + n3 + n4, err
	}

	m.Fid = fid
	m.Name = name
	m.Perm = stat.Mode(perm)
	m.Mode = OpenMode(mod)

	return n1 + n2 + n3 + n4, err
}

/*RCreate is the answer for a successful create.

Qid is the new file as seen by the server.

Iounit may be zero. If not, it is the number of bytes guaranteed
to succeed to be read or written in one message.

See also: http://man.cat-v.org/plan_9/5/open
*/
type RCreate struct {
	Qid    qid.Qid
	Iounit uint32
}

func (m *RCreate) encode(w io.Writer) (int64, error) {
	n1, err := m.Qid.Encode(w)
	if err != nil {
		return n1, err
	}

	n2, err := basic.Uint32Encode(w, m.Iounit)
	if err != nil {
		return n1 + n2, err
	}

	return n1 + n2, nil
}

func (m *RCreate) decode(r io.Reader) (int64, error) {
	n1, err := m.Qid.Decode(r)
	if err != nil {
		return n1, err
	}

	iounit, n2, err := basic.Uint32Decode(r)
	if err != nil {
		return n1 + n2, err
	}

	m.Iounit = iounit

	return n1 + n2, nil
}