1 Star 0 Fork 0

Cloudy/guac

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
instruction.go 2.49 KB
一键复制 编辑 原始数据 按行查看 历史
package guac
import (
"errors"
"fmt"
"strconv"
)
// Instruction represents a Guacamole instruction
type Instruction struct {
Opcode string
Args []string
cache string
}
// NewInstruction creates an instruction
func NewInstruction(opcode string, args ...string) *Instruction {
return &Instruction{
Opcode: opcode,
Args: args,
}
}
// String returns the on-wire representation of the instruction
func (i *Instruction) String() string {
if len(i.cache) > 0 {
return i.cache
}
i.cache = fmt.Sprintf("%d.%s", len(i.Opcode), i.Opcode)
for _, value := range i.Args {
i.cache += fmt.Sprintf(",%d.%s", len(value), value)
}
i.cache += ";"
return i.cache
}
func (i *Instruction) Byte() []byte {
return []byte(i.String())
}
func Parse(buf []byte) (*Instruction, error) {
data := []rune(string(buf))
elementStart := 0
// Build list of elements
elements := make([]string, 0, 1)
for elementStart < len(data) {
// Find end of length
lengthEnd := -1
for i := elementStart; i < len(data); i++ {
if data[i] == '.' {
lengthEnd = i
break
}
}
// read() is required to return a complete instruction. If it does
// not, this is a severe internal error.
if lengthEnd == -1 {
return nil, errors.New("guac.Parse: incomplete instruction")
}
// Parse length
length, e := strconv.Atoi(string(data[elementStart:lengthEnd]))
if e != nil {
return nil, errors.New("guac.Parse: wrong pattern instruction")
}
// Parse element from just after period
elementStart = lengthEnd + 1
elementEnd := elementStart + length
if elementEnd >= len(data) {
return nil, errors.New("guac.Parse: invalid length (corrupted instruction?)")
}
element := string(data[elementStart:elementEnd])
// Append element to list of elements
elements = append(elements, element)
// ReadSome terminator after element
elementStart += length
if elementStart >= len(data) {
return nil, errors.New("guac.Parse: invalid length (corrupted instruction?)")
}
terminator := data[elementStart]
// Continue reading instructions after terminator
elementStart++
// If we've reached the end of the instruction
if terminator == ';' {
break
}
}
return NewInstruction(elements[0], elements[1:]...), nil
}
// ReadOne takes an instruction from the stream and parses it into an Instruction
func ReadOne(stream *Stream) (instruction *Instruction, err error) {
var instructionBuffer []byte
instructionBuffer, err = stream.ReadSome()
if err != nil {
return
}
return Parse(instructionBuffer)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/itcloudy/guac.git
git@gitee.com:itcloudy/guac.git
itcloudy
guac
guac
master

搜索帮助