Files
sshwifty-udp-telnet-http/application/commands/string.go
2022-04-15 18:49:03 +08:00

104 lines
2.2 KiB
Go

// Sshwifty - A Web SSH client
//
// Copyright (C) 2019-2022 Ni Rui <ranqus@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package commands
import (
"errors"
"github.com/nirui/sshwifty/application/rw"
)
// Errors
var (
ErrStringParseBufferTooSmall = errors.New(
"not enough buffer space to parse given string")
ErrStringMarshalBufferTooSmall = errors.New(
"not enough buffer space to marshal given string")
)
// String data
type String struct {
len Integer
data []byte
}
// ParseString build the String according to readed data
func ParseString(reader rw.ReaderFunc, b []byte) (String, error) {
lenData := Integer(0)
mErr := lenData.Unmarshal(reader)
if mErr != nil {
return String{}, mErr
}
bLen := len(b)
if bLen < lenData.Int() {
return String{}, ErrStringParseBufferTooSmall
}
_, rErr := rw.ReadFull(reader, b[:lenData])
if rErr != nil {
return String{}, rErr
}
return String{
len: lenData,
data: b[:lenData],
}, nil
}
// NewString create a new String
func NewString(d []byte) String {
dLen := len(d)
if dLen > MaxInteger {
panic("Data was too long for a String")
}
return String{
len: Integer(dLen),
data: d,
}
}
// Data returns the data of the string
func (s String) Data() []byte {
return s.data
}
// Marshal the string to give buffer
func (s String) Marshal(b []byte) (int, error) {
bLen := len(b)
if bLen < s.len.ByteSize()+len(s.data) {
return 0, ErrStringMarshalBufferTooSmall
}
mLen, mErr := s.len.Marshal(b)
if mErr != nil {
return 0, mErr
}
return copy(b[mLen:], s.data) + mLen, nil
}