diff --git a/27-functions-advanced/07-deferred-funcs/main.go b/28-error-handling/01-deferred-funcs/main.go similarity index 100% rename from 27-functions-advanced/07-deferred-funcs/main.go rename to 28-error-handling/01-deferred-funcs/main.go diff --git a/27-functions-advanced/08-png-detector/main.go b/28-error-handling/02-png-detector/main.go similarity index 83% rename from 27-functions-advanced/08-png-detector/main.go rename to 28-error-handling/02-png-detector/main.go index c0c28a5..6594ce0 100644 --- a/27-functions-advanced/08-png-detector/main.go +++ b/28-error-handling/02-png-detector/main.go @@ -14,25 +14,6 @@ import ( "os" ) -/* - // Most other languages do this: - try { - // open a file - // throws an exception - } catch (ExceptionType name) { - // handle the error - } finally { - // close the file - } - - // Go way: - file, err := // open the file - if err != nil { - // handle the error - } - // close the file -*/ - func main() { files := []string{ "pngs/cups-jpg.png", @@ -43,11 +24,11 @@ func main() { "pngs/empty.png", } - pngs := detect(files) + valids := detect(files) fmt.Printf("Correct Files:\n") - for _, png := range pngs { - fmt.Printf(" + %s\n", png) + for _, valid := range valids { + fmt.Printf(" + %s\n", valid) } } @@ -89,7 +70,7 @@ func read(filename string, buf []byte) error { return err } -func detectPNGUnsafeAndVerbose(filenames []string) (pngs []string) { +func detectPNGUnsafeAndVerbose(filenames []string) (valids []string) { const pngHeader = "\x89PNG\r\n\x1a\n" buf := make([]byte, len(pngHeader)) @@ -118,7 +99,7 @@ func detectPNGUnsafeAndVerbose(filenames []string) (pngs []string) { } if bytes.Equal([]byte(pngHeader), buf) { - pngs = append(pngs, filename) + valids = append(valids, filename) } } return diff --git a/27-functions-advanced/08-png-detector/pngs/cups-jpg.png b/28-error-handling/02-png-detector/pngs/cups-jpg.png similarity index 100% rename from 27-functions-advanced/08-png-detector/pngs/cups-jpg.png rename to 28-error-handling/02-png-detector/pngs/cups-jpg.png diff --git a/27-functions-advanced/08-png-detector/pngs/empty.png b/28-error-handling/02-png-detector/pngs/empty.png similarity index 100% rename from 27-functions-advanced/08-png-detector/pngs/empty.png rename to 28-error-handling/02-png-detector/pngs/empty.png diff --git a/27-functions-advanced/08-png-detector/pngs/forest-jpg.png b/28-error-handling/02-png-detector/pngs/forest-jpg.png similarity index 100% rename from 27-functions-advanced/08-png-detector/pngs/forest-jpg.png rename to 28-error-handling/02-png-detector/pngs/forest-jpg.png diff --git a/27-functions-advanced/08-png-detector/pngs/golden.png b/28-error-handling/02-png-detector/pngs/golden.png similarity index 100% rename from 27-functions-advanced/08-png-detector/pngs/golden.png rename to 28-error-handling/02-png-detector/pngs/golden.png diff --git a/27-functions-advanced/08-png-detector/pngs/shakespeare-text.png b/28-error-handling/02-png-detector/pngs/shakespeare-text.png similarity index 100% rename from 27-functions-advanced/08-png-detector/pngs/shakespeare-text.png rename to 28-error-handling/02-png-detector/pngs/shakespeare-text.png diff --git a/27-functions-advanced/08-png-detector/pngs/work.png b/28-error-handling/02-png-detector/pngs/work.png similarity index 100% rename from 27-functions-advanced/08-png-detector/pngs/work.png rename to 28-error-handling/02-png-detector/pngs/work.png diff --git a/28-error-handling/03-png-detector-with-panic/main.go b/28-error-handling/03-png-detector-with-panic/main.go new file mode 100644 index 0000000..1c56071 --- /dev/null +++ b/28-error-handling/03-png-detector-with-panic/main.go @@ -0,0 +1,111 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "bytes" + "fmt" + "io" + "os" +) + +/* + // ~~~ THE CLASSIC WAY ~~~ + try { + // open a file + // throws an exception + } catch (ExceptionType name) { + // handle the error + } finally { + // close the file + } + + // ~~~ GO WAY ~~~ + file, err := // open the file + if err != nil { + // handle the error + } + // close the file + + // really really exceptional problem occurs + // mostly due to a programmer + + // panic("PANIC PANIC") +*/ + +func main() { + files := []string{ + "pngs/cups-jpg.png", + "pngs/forest-jpg.png", + "pngs/golden.png", + "pngs/work.png", + "pngs/shakespeare-text.png", + "pngs/empty.png", + } + + list("png", files) + + // fmt.Println("catch me if you can!") +} + +func list(format string, files []string) { + valids := detect(format, files) + + fmt.Printf("Correct Files:\n") + for _, valid := range valids { + fmt.Printf(" + %s\n", valid) + } +} + +func detect(format string, filenames []string) (valids []string) { + header := headerOf(format) + + buf := make([]byte, len(header)) + + for _, filename := range filenames { + if read(filename, buf) != nil { + continue + } + + if bytes.Equal([]byte(header), buf) { + valids = append(valids, filename) + } + } + return +} + +func headerOf(format string) string { + switch format { + case "png": + return "\x89PNG\r\n\x1a\n" + case "jpg": + return "\xff\xd8\xff" + } + panic("unknown format: " + format) +} + +// read reads len(buf) bytes to buf from a file +func read(filename string, buf []byte) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + + fi, err := file.Stat() + if err != nil { + return err + } + + if fi.Size() <= int64(len(buf)) { + return fmt.Errorf("file size < len(buf)") + } + + _, err = io.ReadFull(file, buf) + return err +} diff --git a/28-error-handling/03-png-detector-with-panic/pngs/cups-jpg.png b/28-error-handling/03-png-detector-with-panic/pngs/cups-jpg.png new file mode 100755 index 0000000..7c0542d Binary files /dev/null and b/28-error-handling/03-png-detector-with-panic/pngs/cups-jpg.png differ diff --git a/28-error-handling/03-png-detector-with-panic/pngs/empty.png b/28-error-handling/03-png-detector-with-panic/pngs/empty.png new file mode 100644 index 0000000..e69de29 diff --git a/28-error-handling/03-png-detector-with-panic/pngs/forest-jpg.png b/28-error-handling/03-png-detector-with-panic/pngs/forest-jpg.png new file mode 100755 index 0000000..2b25dcf Binary files /dev/null and b/28-error-handling/03-png-detector-with-panic/pngs/forest-jpg.png differ diff --git a/28-error-handling/03-png-detector-with-panic/pngs/golden.png b/28-error-handling/03-png-detector-with-panic/pngs/golden.png new file mode 100644 index 0000000..00827bd Binary files /dev/null and b/28-error-handling/03-png-detector-with-panic/pngs/golden.png differ diff --git a/28-error-handling/03-png-detector-with-panic/pngs/shakespeare-text.png b/28-error-handling/03-png-detector-with-panic/pngs/shakespeare-text.png new file mode 100644 index 0000000..cd46cce --- /dev/null +++ b/28-error-handling/03-png-detector-with-panic/pngs/shakespeare-text.png @@ -0,0 +1,12 @@ +come night come romeo come thou day in night +for thou wilt lie upon the wings of night +whiter than new snow on a raven's back +come gentle night come loving black-browed night +give me my romeo and when he shall die +take him and cut him out in little stars +and he will make the face of heaven so fine +that all the world will be in love with night +and pay no worship to the garish sun +oh i have bought the mansion of love +but not possessed it and though i am sold +not yet enjoyed \ No newline at end of file diff --git a/28-error-handling/03-png-detector-with-panic/pngs/work.png b/28-error-handling/03-png-detector-with-panic/pngs/work.png new file mode 100644 index 0000000..75787b2 Binary files /dev/null and b/28-error-handling/03-png-detector-with-panic/pngs/work.png differ diff --git a/28-error-handling/04-image-detector-recover/main.go b/28-error-handling/04-image-detector-recover/main.go new file mode 100644 index 0000000..5854d0e --- /dev/null +++ b/28-error-handling/04-image-detector-recover/main.go @@ -0,0 +1,99 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "bytes" + "fmt" + "io" + "os" +) + +func main() { + defer func() { + if rerr := recover(); rerr != nil { + fmt.Println("panicked:", rerr) + } + }() + + files := []string{ + "pngs/cups-jpg.png", + "pngs/forest-jpg.png", + "pngs/golden.png", + "pngs/work.png", + "pngs/shakespeare-text.png", + "pngs/empty.png", + } + + args := os.Args[1:] + if len(args) != 1 { + fmt.Println("png or jpg?") + return + } + + list(args[0], files) + + // fmt.Println("catch me if you can!") +} + +func list(format string, files []string) { + valids := detect(format, files) + + fmt.Printf("Correct Files:\n") + for _, valid := range valids { + fmt.Printf(" + %s\n", valid) + } +} + +func detect(format string, filenames []string) (pngs []string) { + header := headerOf(format) + buf := make([]byte, len(header)) + + for _, filename := range filenames { + if read(filename, buf) != nil { + continue + } + + if bytes.Equal([]byte(header), buf) { + pngs = append(pngs, filename) + } + } + return +} + +func headerOf(format string) string { + switch format { + case "png": + return "\x89PNG\r\n\x1a\n" + case "jpg": + return "\xff\xd8\xff" + } + // this should never occur + panic("unknown format: " + format) +} + +// read reads len(buf) bytes to buf from a file +func read(filename string, buf []byte) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + + fi, err := file.Stat() + if err != nil { + return err + } + + if fi.Size() <= int64(len(buf)) { + return fmt.Errorf("file size < len(buf)") + } + + _, err = io.ReadFull(file, buf) + return err +} diff --git a/28-error-handling/04-image-detector-recover/pngs/cups-jpg.png b/28-error-handling/04-image-detector-recover/pngs/cups-jpg.png new file mode 100755 index 0000000..7c0542d Binary files /dev/null and b/28-error-handling/04-image-detector-recover/pngs/cups-jpg.png differ diff --git a/28-error-handling/04-image-detector-recover/pngs/empty.png b/28-error-handling/04-image-detector-recover/pngs/empty.png new file mode 100644 index 0000000..e69de29 diff --git a/28-error-handling/04-image-detector-recover/pngs/forest-jpg.png b/28-error-handling/04-image-detector-recover/pngs/forest-jpg.png new file mode 100755 index 0000000..2b25dcf Binary files /dev/null and b/28-error-handling/04-image-detector-recover/pngs/forest-jpg.png differ diff --git a/28-error-handling/04-image-detector-recover/pngs/golden.png b/28-error-handling/04-image-detector-recover/pngs/golden.png new file mode 100644 index 0000000..00827bd Binary files /dev/null and b/28-error-handling/04-image-detector-recover/pngs/golden.png differ diff --git a/28-error-handling/04-image-detector-recover/pngs/shakespeare-text.png b/28-error-handling/04-image-detector-recover/pngs/shakespeare-text.png new file mode 100644 index 0000000..cd46cce --- /dev/null +++ b/28-error-handling/04-image-detector-recover/pngs/shakespeare-text.png @@ -0,0 +1,12 @@ +come night come romeo come thou day in night +for thou wilt lie upon the wings of night +whiter than new snow on a raven's back +come gentle night come loving black-browed night +give me my romeo and when he shall die +take him and cut him out in little stars +and he will make the face of heaven so fine +that all the world will be in love with night +and pay no worship to the garish sun +oh i have bought the mansion of love +but not possessed it and though i am sold +not yet enjoyed \ No newline at end of file diff --git a/28-error-handling/04-image-detector-recover/pngs/work.png b/28-error-handling/04-image-detector-recover/pngs/work.png new file mode 100644 index 0000000..75787b2 Binary files /dev/null and b/28-error-handling/04-image-detector-recover/pngs/work.png differ diff --git a/28-error-handling/04-image-detector-recoverxxx/main.go b/28-error-handling/04-image-detector-recoverxxx/main.go new file mode 100644 index 0000000..89963ec --- /dev/null +++ b/28-error-handling/04-image-detector-recoverxxx/main.go @@ -0,0 +1,49 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "os" + + "github.com/inancgumus/learngo/internal/magic" +) + +func main() { + files := []string{ + "pngs/cups-jpg.png", + "pngs/forest-jpg.png", + "pngs/golden.png", + "pngs/work.png", + "pngs/shakespeare-text.png", + "pngs/empty.png", + } + + args := os.Args[1:] + if len(args) != 1 { + fmt.Println("png or jpg?") + return + } + + list(args[0], files) + + // fmt.Println("catch me if you can!") +} + +func list(format string, files []string) { + valids, err := magic.Detect(format, files) + if err != nil { + fmt.Println(err) + return + } + + fmt.Printf("Correct Files:\n") + for _, valid := range valids { + fmt.Printf(" + %s\n", valid) + } +} diff --git a/28-error-handling/04-image-detector-recoverxxx/pngs/cups-jpg.png b/28-error-handling/04-image-detector-recoverxxx/pngs/cups-jpg.png new file mode 100755 index 0000000..7c0542d Binary files /dev/null and b/28-error-handling/04-image-detector-recoverxxx/pngs/cups-jpg.png differ diff --git a/28-error-handling/04-image-detector-recoverxxx/pngs/empty.png b/28-error-handling/04-image-detector-recoverxxx/pngs/empty.png new file mode 100644 index 0000000..e69de29 diff --git a/28-error-handling/04-image-detector-recoverxxx/pngs/forest-jpg.png b/28-error-handling/04-image-detector-recoverxxx/pngs/forest-jpg.png new file mode 100755 index 0000000..2b25dcf Binary files /dev/null and b/28-error-handling/04-image-detector-recoverxxx/pngs/forest-jpg.png differ diff --git a/28-error-handling/04-image-detector-recoverxxx/pngs/golden.png b/28-error-handling/04-image-detector-recoverxxx/pngs/golden.png new file mode 100644 index 0000000..00827bd Binary files /dev/null and b/28-error-handling/04-image-detector-recoverxxx/pngs/golden.png differ diff --git a/28-error-handling/04-image-detector-recoverxxx/pngs/shakespeare-text.png b/28-error-handling/04-image-detector-recoverxxx/pngs/shakespeare-text.png new file mode 100644 index 0000000..cd46cce --- /dev/null +++ b/28-error-handling/04-image-detector-recoverxxx/pngs/shakespeare-text.png @@ -0,0 +1,12 @@ +come night come romeo come thou day in night +for thou wilt lie upon the wings of night +whiter than new snow on a raven's back +come gentle night come loving black-browed night +give me my romeo and when he shall die +take him and cut him out in little stars +and he will make the face of heaven so fine +that all the world will be in love with night +and pay no worship to the garish sun +oh i have bought the mansion of love +but not possessed it and though i am sold +not yet enjoyed \ No newline at end of file diff --git a/28-error-handling/04-image-detector-recoverxxx/pngs/work.png b/28-error-handling/04-image-detector-recoverxxx/pngs/work.png new file mode 100644 index 0000000..75787b2 Binary files /dev/null and b/28-error-handling/04-image-detector-recoverxxx/pngs/work.png differ diff --git a/internal/magic/detect.go b/internal/magic/detect.go new file mode 100644 index 0000000..f67dfc0 --- /dev/null +++ b/internal/magic/detect.go @@ -0,0 +1,74 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package magic + +import ( + "bytes" + "fmt" + "io" + "os" +) + +// Detect returns only the valid filenames that match to a header of the given format. +func Detect(format string, filenames []string) (valids []string, err error) { + defer func() { + if rerr := recover(); rerr != nil { + err = fmt.Errorf("cannot detect: %v", rerr) + } + }() + + return detect(format, filenames), nil +} + +func detect(format string, filenames []string) (valids []string) { + header := headerOf(format) + buf := make([]byte, len(header)) + + for _, filename := range filenames { + if read(filename, buf) != nil { + continue + } + + if bytes.Equal([]byte(header), buf) { + valids = append(valids, filename) + } + } + return +} + +func headerOf(format string) string { + switch format { + case "png": + return "\x89PNG\r\n\x1a\n" + case "jpg": + return "\xff\xd8\xff" + } + // this should never occur + panic("unknown format: " + format) +} + +// read reads len(buf) bytes to buf from a file +func read(filename string, buf []byte) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + + fi, err := file.Stat() + if err != nil { + return err + } + + if fi.Size() <= int64(len(buf)) { + return fmt.Errorf("file size < len(buf)") + } + + _, err = io.ReadFull(file, buf) + return err +}