Does Go fmt indent automatically? - unix

When I do fmt.Printf("...\n") it doesn't move the cursor to the 0th column and the next line is therefore indented:
13
13
13
13
13
13
113 ('q')
Here is my code:
package main
import (
"bufio"
"fmt"
"os"
"unicode"
"golang.org/x/crypto/ssh/terminal"
)
func main() {
oldState, err := terminal.MakeRaw(0)
if err != nil {
panic(err)
}
defer terminal.Restore(0, oldState)
reader := bufio.NewReader(os.Stdin)
var c rune
for err == nil {
if c == 'q' {
break
}
c, _, err = reader.ReadRune()
if unicode.IsControl(c) {
fmt.Printf("%d\n", c)
} else {
fmt.Printf("%d ('%c')\n", c, c)
}
}
if err != nil {
panic(err)
}
}

Comment: You're putting the terminal in raw mode, doesn't that require a
carriage return to put the cursor at the start of the line? – JimB
For example,
terminal.go:
package main
import (
"bufio"
"fmt"
"os"
"unicode"
"golang.org/x/crypto/ssh/terminal"
)
func main() {
oldState, err := terminal.MakeRaw(0)
if err != nil {
panic(err)
}
defer terminal.Restore(0, oldState)
reader := bufio.NewReader(os.Stdin)
var c rune
for err == nil {
if c == 'q' {
break
}
c, _, err = reader.ReadRune()
if unicode.IsControl(c) {
fmt.Printf("%d\r\n", c)
} else {
fmt.Printf("%d ('%c')\r\n", c, c)
}
}
if err != nil {
panic(err)
}
}
Output:
$ go run terminal.go
13
13
13
13
13
113 ('q')
$

Related

SQL query hangs or crashes

Following code on Go 1.16.6 hangs on last Exec call (or crashes if same functions are called from different goroutines)
Both libraries "github.com/mattn/go-sqlite3" and "modernc.org/sqlite" give same results
package main
import (
"os"
"testing"
"database/sql"
_ "github.com/mattn/go-sqlite3"
// _ "modernc.org/sqlite"
)
func Test_Bug3(t *testing.T) {
DBPath := "test.db"
os.Remove(DBPath)
DB, err := sql.Open("sqlite3", DBPath)
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
if _, err := DB.Exec(`CREATE TABLE IF NOT EXISTS verdictcache (sha1 text);`); err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Query("SELECT * FROM verdictcache WHERE sha1=$1", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "b")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
}
What is happening is almost certainly that you did not call Close() (or otherwise consumed the rows) on the result returned by DB.Query(...).
Try:
func Test_Bug3(t *testing.T) {
DBPath := "test.db"
os.Remove(DBPath)
DB, err := sql.Open("sqlite3", DBPath)
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
if _, err := DB.Exec(`CREATE TABLE IF NOT EXISTS verdictcache (sha1 text);`); err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
res, err := DB.Query("SELECT * FROM verdictcache WHERE sha1=$1", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
res.Close()
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "b")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
}

How to open tab in new window of the same browser with chromedp?

How to open tab in new window of the same browser?
Some web applications do not work in an inactive tab.
In the example, several windows open, but only the first window is available for management. When creating the rest, an error occurs
chrome failed to start: A window or tab will open in the current browser session.
package main
import (
"context"
"log"
"time"
"github.com/chromedp/chromedp"
)
func main() {
userDir := "someUserDir"
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.DisableGPU,
chromedp.UserDataDir(userDir),
chromedp.WindowSize(1368, 768),
chromedp.Flag("headless", false),
chromedp.Flag("enable-automation", false),
chromedp.Flag("restore-on-startup", false),
chromedp.Flag("new-window", true),
)
for i := 0; i < 5; i++ {
log.Printf("open window %d", i)
allocCtx, _ := chromedp.NewExecAllocator(context.Background(), opts...)
ctx, _ := chromedp.NewContext(allocCtx)
if err := chromedp.Run(ctx, chromedp.Navigate("https://example.com")); err != nil {
log.Println(err)
}
}
time.Sleep(time.Minute)
}
package main
import (
"context"
"log"
"time"
"github.com/chromedp/cdproto/runtime"
"github.com/chromedp/chromedp"
)
func main() {
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.DisableGPU,
chromedp.UserDataDir("someUserDir"),
chromedp.Flag("headless", false),
chromedp.Flag("enable-automation", false),
chromedp.Flag("restore-on-startup", false),
)
allocCtx, _ := chromedp.NewExecAllocator(context.Background(), opts...)
ctx, _ := chromedp.NewContext(allocCtx)
if err := chromedp.Run(ctx, chromedp.Navigate("about:blank")); err != nil {
log.Fatalln(err)
}
for i := 0; i < 5; i++ {
var res *runtime.RemoteObject
if err := chromedp.Run(ctx, chromedp.Evaluate(`window.open("about:blank", "", "resizable,scrollbars,status")`, &res)); err != nil {
log.Fatalln(err)
}
targets, err := chromedp.Targets(ctx)
if err != nil {
log.Fatalln(err)
}
for _, t := range targets {
if !t.Attached {
newCtx, _ := chromedp.NewContext(ctx, chromedp.WithTargetID(t.TargetID))
if err := chromedp.Run(newCtx, chromedp.Navigate("https://example.com")); err != nil {
log.Fatalln(err)
}
}
}
}
time.Sleep(time.Minute)
}

Calling winapi function in golang with struct union

I am trying to call the TransmitPackets function on windows using GO.
The goal is to be able to send multiple packets with one syscall (can't be achieved with WSASend [it'll send fragmented IP packets]).
My code panics
panic: write udp 192.168.1.26:51817->8.8.8.8:8000: transmitpackets: An invalid argument was supplied.
goroutine 1 [running]:
main.main()
c:/Users/amit/dev/go/src/rio/main.go:26 +0x210
exit status 2
Process exiting with code: 1
Here's my test code
package main
import (
"math/rand"
"net"
)
func main() {
raddr, err := net.ResolveUDPAddr("udp", "8.8.8.8:8000")
if err != nil {
panic(err)
}
con, err := net.DialUDP("udp", nil, raddr)
if err != nil {
panic(err)
}
packets := make(net.Buffers, 10)
for i := 0; i < len(packets); i++ {
packets[i] = make([]byte, 1400)
rand.Read(packets[i])
}
_, err = con.WriteMultiple(packets)
if err != nil {
panic(err)
}
}
and Here's my call to TransmitPackets:
type TransmitPacketsElement struct {
dwElFlags uint32
cLength uint32
pBuffer unsafe.Pointer
nFileOffset uint64
hFile uintptr
}
func transmitPackets(s Handle, bufs [][]byte, overlapped *Overlapped) (err error) {
var maxPacketLen = 0
tpElements := make([]TransmitPacketsElement, len(bufs))
for i, tpElement := range tpElements {
buffer := bufs[i]
if len(buffer) > maxPacketLen {
maxPacketLen = len(buffer)
}
tpElement.cLength = uint32(len(buffer))
tpElement.dwElFlags = uint32(uint32(TP_ELEMENT_MEMORY) | uint32(TP_ELEMENT_EOP))
tpElement.pBuffer = unsafe.Pointer(&buffer[0])
}
r1, _, e1 := Syscall6(transmitPacketsFunc.addr, 6, uintptr(s), uintptr(unsafe.Pointer(&tpElements[0])), uintptr(uint32(len(tpElements))), uintptr(uint32(maxPacketLen)), uintptr(unsafe.Pointer(overlapped)), 0)
if r1 == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = EINVAL
}
}
return
}
You can see the full implementation in my modified go 1.8.3 source on github

Asynchronous messages golang

I have a golang server doing something like this:
package main
func main() {
for {
c := listener.Accept()
go handle(c)
}
}
...
func handle(c net.Conn) {
m := readMessage(c) // func(net.Conn)Message
r := processMessage(m) //func(Message)Result
sendResult(c, r) // func(net.Conn,Result)
}
Which reads and writes messages synchronously. What I need now is to send messages asynchronously through a given open connection, I know a channel can be used by I'm kind of lost.
This is my idea:
...
func someWhereElese(c chan Result) {
// generate a message and a result
r := createResultFromSomewhere()
c <- r // send the result through the channel
}
And modify my handle to use that same channel instead
func handle(c net.Conn, rc chan Result) {
m := readMessage(c) // func(net.Conn)Message
r := processMessage(m) //func(Message)Result
//sendResult(c, r) // func(net.Conn,Result)
rc <- r
}
And here's where my confusion lies.
The result channel should be created and it should have a connection where to send whatever it receives
func doSend(c net.Con, rc chan Result) {
r := rc // got a result channel
sendResult(c, r) // send it through the wire
}
But where should that channel be created? In the main loop?
func main() {
...
for {
c := l.Accept()
rc := make(chan Result)
go doSend(c, rc)
}
}
What about the read? Should it go in it's own channel/gorutine?
If I need to broadcast to n clients, should I keep a slice of result channels? a slice of connections?
I'm kind of confused here, but I feel I'm close.
This program seems to solve my immediate question
package main
import (
"bytes"
"encoding/binary"
"log"
"net"
)
var rcs []chan int = make([]chan int,0)
func main() {
a, e := net.ResolveTCPAddr("tcp", ":8082")
if e != nil {
log.Fatal(e)
}
l, e := net.ListenTCP("tcp", a)
for {
c, e := l.Accept()
if e != nil {
log.Fatal(e)
}
rc := make(chan int)
go read(c, rc)
go write(c, rc)
rcs = append(rcs, rc)
// simulate broacast
log.Println(len(rcs))
if len(rcs) > 5 {
func() {
for _, v := range rcs {
log.Println("sending")
select {
case v <- 34:
log.Println("done sending")
default:
log.Println("didn't send")
}
}
}()
}
}
}
func read(c net.Conn, rc chan int) {
h := make([]byte, 2)
for {
_, err := c.Read(h)
if err != nil {
rc <- -1
}
var v int16
binary.Read(bytes.NewReader(h[:2]), binary.BigEndian, &v)
rc <- int(v)
}
}
func write(c net.Conn, rc chan int) {
for {
r := <-rc
o := []byte{byte(r * 2)}
c.Write(o)
}
}

How to cast reflect.Value to its type?

How to cast reflect.Value to its type?
type Cat struct {
Age int
}
cat := reflect.ValueOf(obj)
fmt.Println(cat.Type()) // Cat
fmt.Println(Cat(cat).Age) // doesn't compile
fmt.Println((cat.(Cat)).Age) // same
Thanks!
concreteCat,_ := reflect.ValueOf(cat).Interface().(Cat)
see http://golang.org/doc/articles/laws_of_reflection.html
fox example
type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)
y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)
Ok, I found it
reflect.Value has a function Interface() that converts it to interface{}
This func auto-converts types as needed. It loads a config file values into a simple struct based on struct name and fields:
import (
"fmt"
toml "github.com/pelletier/go-toml"
"log"
"os"
"reflect"
)
func LoadConfig(configFileName string, configStruct interface{}) {
defer func() {
if r := recover(); r != nil {
fmt.Println("LoadConfig.Recovered: ", r)
}
}()
conf, err := toml.LoadFile(configFileName)
if err == nil {
v := reflect.ValueOf(configStruct)
typeOfS := v.Elem().Type()
sectionName := getTypeName(configStruct)
for i := 0; i < v.Elem().NumField(); i++ {
if v.Elem().Field(i).CanInterface() {
kName := conf.Get(sectionName + "." + typeOfS.Field(i).Name)
kValue := reflect.ValueOf(kName)
if (kValue.IsValid()) {
v.Elem().Field(i).Set(kValue.Convert(typeOfS.Field(i).Type))
}
}
}
} else {
fmt.Println("LoadConfig.Error: " + err.Error())
}
}
Seems the only way would be to do a switch statement similar to (code below) (also, something like the commented line would've-been nice though doesn't work (:()):
func valuesFromStruct (rawV interface{}) []interface{} {
v := reflect.ValueOf(rawV)
out := make([]interface{}, 0)
for i := 0; i < v.NumField(); i += 1 {
field := v.Field(i)
fieldType := field.Type()
// out = append(out, field.Interface().(reflect.PtrTo(fieldType)))
switch (fieldType.Name()) {
case "int64":
out = append(out, field.Interface().(int64))
break`enter code here`
case "float64":
out = append(out, field.Interface().(float64))
break
case "string":
out = append(out, field.Interface().(string))
break
// And all your other types (here) ...
default:
out = append(out, field.Interface())
break
}
}
return out
}
Cheers!

Resources