Created
March 14, 2019 13:25
-
-
Save peterhellberg/8da1f8d13c76d7fbf710cf1af1c9de03 to your computer and use it in GitHub Desktop.
s3270 package for Go, based on https://github.com/msalcantara/go3270
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package s3270 | |
import ( | |
"fmt" | |
"log" | |
"os/exec" | |
"strings" | |
"time" | |
) | |
const ( | |
Enter = "Enter" | |
Tab = "Tab" | |
F1 = "PF(1)" | |
F2 = "PF(2)" | |
F3 = "PF(3)" | |
F4 = "PF(4)" | |
F5 = "PF(5)" | |
F6 = "PF(6)" | |
F7 = "PF(7)" | |
F8 = "PF(8)" | |
F9 = "PF(9)" | |
F10 = "PF(10)" | |
F11 = "PF(11)" | |
F12 = "PF(12)" | |
) | |
var ( | |
ErrNoAddr = fmt.Errorf("no Addr specified") | |
ErrAlreadyConnected = fmt.Errorf("already connected") | |
) | |
func NewEmulator(addr, scriptPort string) Emulator { | |
return Emulator{ | |
Addr: addr, | |
ScriptPort: scriptPort, | |
} | |
} | |
type Emulator struct { | |
Addr string | |
ScriptPort string | |
} | |
func (e *Emulator) Connect() error { | |
if e.Addr == "" { | |
return ErrNoAddr | |
} | |
if e.IsConnected() { | |
return ErrAlreadyConnected | |
} | |
if e.ScriptPort == "" { | |
e.ScriptPort = "5000" | |
} | |
e.connect() | |
if !e.IsConnected() { | |
e.exec("quit") | |
log.Fatalf("error connecting to %s", e.Addr) | |
} | |
return nil | |
} | |
func (e *Emulator) Disconnect() error { | |
if e.IsConnected() { | |
return e.exec("quit") | |
} | |
time.Sleep(time.Second) | |
return nil | |
} | |
func (e *Emulator) ConnectionState() (string, error) { | |
return e.query("ConnectionState") | |
} | |
func (e *Emulator) IsConnected() bool { | |
if s, err := e.ConnectionState(); err != nil || len(strings.TrimSpace(s)) == 0 { | |
return false | |
} | |
return true | |
} | |
func (e *Emulator) FillString(x, y int, value string) error { | |
if err := e.MoveCursor(x, y); err != nil { | |
return fmt.Errorf("move cursor error: %v", err) | |
} | |
return e.SetString(value) | |
} | |
func (e *Emulator) SetString(value string) error { | |
return e.exec(command("String(%s)", value)) | |
} | |
func (e *Emulator) Press(key string) error { | |
if !e.validaKeyboard(key) { | |
return fmt.Errorf("invalid key %s", key) | |
} | |
return e.exec(key) | |
} | |
func (e *Emulator) Value(x, y, l int) (string, error) { | |
return e.execOutput(command("Ascii(%d,%d,%d)", x, y, l)) | |
} | |
func (e *Emulator) Cursor() (string, error) { | |
return e.query("cursor") | |
} | |
func (e *Emulator) MoveCursor(x, y int) error { | |
return e.exec(command("MoveCursor(%d,%d)", x, y)) | |
} | |
func (e *Emulator) validaKeyboard(key string) bool { | |
switch key { | |
case Tab: | |
return true | |
case Enter: | |
return true | |
default: | |
return false | |
} | |
} | |
func (e *Emulator) query(keyword string) (string, error) { | |
return e.execOutput(command("query(%s)", keyword)) | |
} | |
func (e *Emulator) connect() { | |
cmd := exec.Command("s3270", "-scriptport", e.ScriptPort, e.Addr) | |
cmd.Start() | |
go func() { | |
if err := cmd.Wait(); err != nil { | |
log.Fatalf("error to create an instance of 3270\n%v\n", err) | |
} | |
}() | |
time.Sleep(4 * time.Second) | |
} | |
func (e *Emulator) exec(arg string) error { | |
if err := exec.Command("x3270if", "-t", e.ScriptPort, arg).Run(); err != nil { | |
return err | |
} | |
return nil | |
} | |
func (e *Emulator) execOutput(arg string) (string, error) { | |
b, err := exec.Command("x3270if", "-t", e.ScriptPort, arg).Output() | |
if err != nil { | |
return "", err | |
} | |
return string(b), nil | |
} | |
func command(format string, a ...interface{}) string { | |
return fmt.Sprintf(format, a...) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment