1
0
Fork 0

initial commit

This commit is contained in:
ston1th 2019-02-11 23:58:53 +01:00
commit dc421f035e
8 changed files with 989 additions and 0 deletions

202
pkg/encode/encode.go Normal file
View file

@ -0,0 +1,202 @@
package encode
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
"git.giftfish.de/ston1th/duckycode/pkg/lang"
)
type Encoder struct {
reader io.Reader
language string
defaultDelay int
delayOverride bool
loop int
repeat bool
}
func NewEncoder(r io.Reader, language string) *Encoder {
if language == "" {
language = "de"
}
return &Encoder{r, language, 0, false, 0, false}
}
func (e *Encoder) Encode() (buf []byte, err error) {
scanner := bufio.NewScanner(e.reader)
for scanner.Scan() {
if err = scanner.Err(); err != nil {
return
}
s := strings.SplitN(scanner.Text(), " ", 2)
switch len(s) {
case 1:
if b := e.instruction(s[0]); b != 0 {
fmt.Fprintf(os.Stderr, "%s\n", s[0])
buf = append(buf, []byte{b, 0}...)
fmt.Fprintf(os.Stderr, "%#v\n", buf)
}
case 2:
fmt.Fprintf(os.Stderr, "%s:%s\n", s[0], s[1])
buf = append(buf, e.instructionData(s[0], s[1])...)
fmt.Fprintf(os.Stderr, "%#v\n", buf)
}
if !e.delayOverride && e.defaultDelay > 0 {
delayCounter := e.defaultDelay
for delayCounter > 0 {
buf = append(buf, byte(0))
if delayCounter > 255 {
buf = append(buf, byte(255))
delayCounter -= 255
} else {
buf = append(buf, byte(delayCounter))
delayCounter = 0
}
}
}
}
return
}
func (e *Encoder) instruction(in string) byte {
if b, ok := lang.K["KEY_"+in]; ok {
return b
}
switch in {
case "", "REM":
return 0
case "ESCAPE":
return e.instruction("ESC")
case "DEL":
return e.instruction("DELETE")
case "BREAK":
return e.instruction("PAUSE")
case "CONTROL":
return e.instruction("CTRL")
case "DOWNARROW":
return e.instruction("DOWM")
case "UPARROW":
return e.instruction("UP")
case "LEFTARROW":
return e.instruction("LEFT")
case "RIGHTARROW":
return e.instruction("RIGHT")
case "MENU":
return e.instruction("APP")
case "WINDOWS":
return e.instruction("GUI")
case "PLAY":
return e.instruction("MEDIA_PLAY_PAUSE")
case "MUTE":
return e.instruction("MEDIA_MUTE")
case "VOLUMEUP":
return e.instruction("MEDIA_VOLUME_INC")
case "VOLUMEDOWN":
return e.instruction("MEDIAVOLUME_DEC")
case "SCROLLLOCK":
return e.instruction("SCROLL_LOCK")
case "NUMLOCK":
return e.instruction("NUM_LOCK")
case "CAPSLOCK":
return e.instruction("CAPS_LOCK")
case "CTRL":
return e.instruction("LEFT_CTRL")
case "ALT":
return e.instruction("LEFT_ALT")
case "SHIFT":
return e.instruction("LEFT_SHIFT")
case "ALT-SHIFT":
//TODO
return 0
case "ALT-TAB":
//TODO
return 0
}
return e.encodeRune(rune(in[0]))[0]
}
func (e *Encoder) instructionData(in string, data string) (b []byte) {
switch in {
case "DEFAULT_DELAY", "DEFAULTDELAY":
delay, err := strconv.Atoi(data)
if err == nil {
e.defaultDelay = delay
e.delayOverride = true
}
return nil
case "DELAY":
delay, err := strconv.Atoi(data)
if err != nil {
return nil
}
for delay > 0 {
b = append(b, byte(0))
if delay > 255 {
b = append(b, byte(255))
delay -= 255
} else {
b = append(b, byte(delay))
delay = 0
}
}
e.delayOverride = true
return
case "", "REM":
return nil
case "STRING":
for _, r := range data {
enc := e.encodeRune(r)
if len(enc)%2 != 0 {
enc = append(enc, byte(0))
}
b = append(b, enc...)
}
return
case "CONTROL", "CTRL":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_CTRL"]}
case "ALT":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_ALT"]}
case "SHIFT":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_SHIFT"]}
case "CTRL-ALT":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_CTRL"] | lang.K["MODIFIERKEY_ALT"]}
case "CTRL-SHIFT":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_CTRL"] | lang.K["MODIFIERKEY_SHIFT"]}
case "COMMAND-OPTION":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_LEFT_GUI"] | lang.K["MODIFIERKEY_ALT"]}
case "ALT-SHIFT":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_LEFT_ALT"] | lang.K["MODIFIERKEY_SHIFT"]}
case "WINDOWS", "GUI", "COMMAND":
return []byte{e.instruction(data), lang.K["MODIFIERKEY_LEFT_GUI"]}
}
return []byte{e.instruction(data), 0}
}
func (e *Encoder) encodeRune(r rune) []byte {
var code string
hex := strings.ToUpper(strconv.FormatUint(uint64(r), 16))
switch {
case r < 128:
code = "ASCII_" + hex
case r < 256:
code = "ISO_8859_1_" + hex
default:
code = "UNICODE_" + hex
}
if b, ok := lang.K[code]; ok {
return []byte{b}
} else if k, ok := lang.Langs[e.language][code]; ok {
if k.Mod != 0 {
return []byte{k.Key, k.Mod}
}
return []byte{k.Key}
}
return nil
}