Initial commit
This commit is contained in:
120
application/commands/integer.go
Normal file
120
application/commands/integer.go
Normal file
@@ -0,0 +1,120 @@
|
||||
// Sshwifty - A Web SSH client
|
||||
//
|
||||
// Copyright (C) 2019 Rui NI <nirui@gmx.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/niruix/sshwifty/application/rw"
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
ErrIntegerMarshalNotEnoughBuffer = errors.New(
|
||||
"Not enough buffer to marshal the integer")
|
||||
|
||||
ErrIntegerMarshalTooLarge = errors.New(
|
||||
"Integer cannot be marshalled, because the vaule was too large")
|
||||
)
|
||||
|
||||
// Integer is a 16bit unsigned integer data
|
||||
//
|
||||
// Format:
|
||||
// +-------------------------------------+--------------+
|
||||
// | 1 bit | 7 bits |
|
||||
// +-------------------------------------+--------------+
|
||||
// | 1 when current byte is the end byte | Integer data |
|
||||
// +-------------------------------------+--------------+
|
||||
//
|
||||
// Example:
|
||||
// - 00000000 00000000: 0
|
||||
// - 01111111: 127
|
||||
// - 11111111 01000000: 255
|
||||
type Integer uint16
|
||||
|
||||
const (
|
||||
integerHasNextBit = 0x80
|
||||
integerValueCutter = 0x7f
|
||||
)
|
||||
|
||||
// Consts
|
||||
const (
|
||||
MaxInteger = 0x3fff
|
||||
MaxIntegerBytes = 2
|
||||
)
|
||||
|
||||
// ByteSize returns how many bytes current integer will be encoded into
|
||||
func (i *Integer) ByteSize() int {
|
||||
if *i > integerValueCutter {
|
||||
return 2
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
// Int returns a int of current Integer
|
||||
func (i *Integer) Int() int {
|
||||
return int(*i)
|
||||
}
|
||||
|
||||
// Marshal build serialized data of the integer
|
||||
func (i *Integer) Marshal(b []byte) (int, error) {
|
||||
bLen := len(b)
|
||||
|
||||
if *i > MaxInteger {
|
||||
return 0, ErrIntegerMarshalTooLarge
|
||||
}
|
||||
|
||||
if bLen < i.ByteSize() {
|
||||
return 0, ErrIntegerMarshalNotEnoughBuffer
|
||||
}
|
||||
|
||||
if *i <= integerValueCutter {
|
||||
b[0] = byte(*i & integerValueCutter)
|
||||
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
b[0] = byte((*i >> 7) | integerHasNextBit)
|
||||
b[1] = byte(*i & integerValueCutter)
|
||||
|
||||
return 2, nil
|
||||
}
|
||||
|
||||
// Unmarshal read data and parse the integer
|
||||
func (i *Integer) Unmarshal(reader rw.ReaderFunc) error {
|
||||
buf := [1]byte{}
|
||||
|
||||
for j := 0; j < MaxIntegerBytes; j++ {
|
||||
_, rErr := rw.ReadFull(reader, buf[:])
|
||||
|
||||
if rErr != nil {
|
||||
return rErr
|
||||
}
|
||||
|
||||
*i |= Integer(buf[0] & integerValueCutter)
|
||||
|
||||
if integerHasNextBit&buf[0] == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
*i <<= 7
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user