aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/gocmdbridge/server/readfile.go
blob: ca241702e4bf65b857af75057d962c8edee0854e (plain)
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
package main

import (
	"io"
	"os"

	"github.com/fxamacker/cbor/v2"
)

type readfile struct {
	Path string
	Limit int64
	Offset int64
}

type readfiledata struct {
	Type string
	Id int
	Contents []byte
}

type readfiledone struct {
	Type string
	Id int
}

func processReadFile(cmd command, out chan<- []byte) {
	file, seekErr := os.Open(cmd.ReadFile.Path)
	if seekErr != nil {
		sendError(out, cmd, seekErr)
		return
	}

	size, seekErr := file.Seek(0, io.SeekEnd)
	if seekErr != nil {
		sendError(out, cmd, seekErr)
		return
	}

	_, seekErr = file.Seek(cmd.ReadFile.Offset, 0)
	if seekErr != nil {
		sendError(out, cmd, seekErr)
		return
	}

	readSize := cmd.ReadFile.Limit
	if readSize == -1 {
		readSize = size - cmd.ReadFile.Offset
	}

	for {
		toRead := min(readSize, 4096)
		contents := make([]byte, toRead)
		bytesRead, readErr := file.Read(contents)

		if readErr != nil && readErr != io.EOF {
			sendError(out, cmd, readErr)
			return
		}

		readSize -= int64(bytesRead)

		result, _ := cbor.Marshal(readfiledata{
			Type:     "readfiledata",
			Id:       cmd.Id,
			Contents: contents,
		})
		out <- result

		if readErr == io.EOF || readSize == 0 {
			result, _:= cbor.Marshal(readfiledone{
				Type: "readfiledone",
				Id: cmd.Id,
			})
			out <- result
			return
		}
	}
}