Advertisement
dvulakh

util.go

Mar 4th, 2020
718
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.61 KB | None | 0 0
  1. package util
  2.  
  3. import (
  4.     "sync/atomic"
  5.     "strconv"
  6.     "strings"
  7.     "unsafe"
  8.     "sync"
  9.     "fmt"
  10.     "os"
  11. )
  12.  
  13. /*** FILE UTILITIES ***/
  14.  
  15. // LogFile is a wrapper for files that guarantees writing is atomic.
  16. // LogFile objects can be 'turned off' so that write requests are ignored.
  17. type LogFile struct {
  18.     // LogLock is the LogFile's mutex for writing atomically.
  19.     LogLock *sync.Mutex
  20.     // Log is the LogFile's wrapped File object.
  21.     Log     *os.File
  22.     // On is the boolean flag indicating whether the LogFile will accept write requests.
  23.     On      bool
  24. }
  25.  
  26. // FExists returns true if the file in the given location exists. It returns false otherwise.
  27. func FExists(f string) bool {
  28.     _, err := os.Stat(f)
  29.     if os.IsNotExist(err) {
  30.         return false
  31.     }
  32.     return true
  33. }
  34.  
  35. // FOpen returns a pointer to an os.File in the given location.
  36. // If the file exists and a is true, then the file will be in append mode.
  37. func FOpen(f string, a bool) *os.File {
  38.     if a && FExists(f) {
  39.         t, _ := os.OpenFile(f, os.O_APPEND|os.O_WRONLY, 0600)
  40.         return t
  41.     }
  42.     t, _ := os.Create(f)
  43.     return t
  44. }
  45.  
  46. // MakeLog constructs a LogFile structure using the given file and setting.
  47. func MakeLog(f *os.File, o bool) *LogFile {
  48.     return &LogFile{&sync.Mutex{}, f, o}
  49. }
  50.  
  51. // Write writes the input string to the Log File object if On is true.
  52. // Any following parameters are inserted, formatted as with Printf.
  53. func (log *LogFile) Write(v bool, format string, a ...interface{}) {
  54.     out := fmt.Sprintf(format, a...)
  55.     if log.On {
  56.         log.LogLock.Lock()
  57.         fmt.Fprint(log.Log, out)
  58.         log.LogLock.Unlock()
  59.     }
  60.     if v {
  61.         fmt.Print(out)
  62.     }
  63. }
  64.  
  65. /*** INPUT UTILITIES ***/
  66.  
  67. // ReadInfo is a general function for taking command line input with a system of one-character flags.
  68. // For each flag, the following whitespace separated block of text is passed as an argument to the corresponding function found in the input maps.
  69. func ReadInfo(line string, argm map[rune]unsafe.Pointer, funm map[rune]func(unsafe.Pointer, rune, string)) {
  70.     com := []rune{}
  71.     set := strings.Fields(line)
  72.     for _, s := range set {
  73.         if s[0] == '-' && s[1] != '1' {
  74.             for _, c := range s[1:] {
  75.                 com = append(com, c)
  76.             }
  77.         } else if len(com) > 0 {
  78.             c := com[0]
  79.             com = com[1:]
  80.             if _, ok := argm[c]; ok {
  81.                 funm[c](argm[c], c, s)
  82.             } else {
  83.                 fmt.Printf("Command not recognized: -%s\n", string(c))
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. /*** BASIC UTILITIES ***/
  90.  
  91. // Logger is an interface that provides utility functions with a way to access the commander's log files.
  92. type Logger struct {
  93.     Log *LogFile
  94.     Verb    bool
  95. }
  96.  
  97. // Write writes to a logger's file.
  98. func Write(lgr *Logger, format string, a ...interface{}) { (*(*lgr).Log).Write((*lgr).Verb, format, a...) };
  99.  
  100. // ParseInt takes as an argument a string s representing an integer.
  101. // ParseInt parses and returns an int32 from s.
  102. func ParseInt(s string) int {
  103.     t, _ := strconv.ParseInt(s, 10, 32)
  104.     return int(t)
  105. }
  106.  
  107. // ParseInt takes as an argument a string s representing a decimal value.
  108. // ParseFloat parses and returns a float64 from s.
  109. func ParseFloat(s string) float64 {
  110.     t, _ := strconv.ParseFloat(s, 64)
  111.     return float64(t)
  112. }
  113.  
  114. // Max takes as arguments two integers a and b.
  115. // Max returns the greater of a and b.
  116. func Max(i, j int) int {
  117.     if i > j {
  118.         return i
  119.     }
  120.     return j
  121. }
  122.  
  123. // Min takes as arguments two integers a and b.
  124. // Min returns the smaller of a and b.
  125. func Min(i, j int) int {
  126.     if i > j {
  127.         return j
  128.     }
  129.     return i
  130. }
  131.  
  132. // ToString takes as an argument a slice of integers a.
  133. // ToString converts a to a space-separated string and returns that string.
  134. func ToString(a []int) string {
  135.     s := ""
  136.     if len(a) == 0 {
  137.         return s
  138.     }
  139.     s += strconv.Itoa(a[0])
  140.     for i, n := range a {
  141.         if i > 0 {
  142.             s += " " + strconv.Itoa(n)
  143.         }
  144.     }
  145.     return s
  146. }
  147.  
  148. // ToSlice takes as an argument a string s containing only space-separated integers.
  149. // ToSlice converts s into a slice of int32 and returns that slice.
  150. func ToSlice(s string) []int {
  151.     f := strings.Fields(s)
  152.     a := []int{}
  153.     for _, n := range f {
  154.         a = append(a, ParseInt(n))
  155.     }
  156.     return a
  157. }
  158.  
  159. // Unwrap takes as an argument an interface{} t representing an int32 slice.
  160. // Unwrap returns the int32 slice represented by t.
  161. func Unwrap(t interface{}) []int {
  162.     a := []int{}
  163.     nt, _ := t.([]int)
  164.     for _, n := range nt {
  165.         a = append(a, int(n))
  166.     }
  167.     return a
  168. }
  169.  
  170. // Equals takes as arguments two int32 slices a and b.
  171. // Equals returns true if a and b contain the same elements in the same order and false otherwise.
  172. func Equals(a []int, b []int) bool {
  173.     if len(a) != len(b) {
  174.         return false
  175.     }
  176.     for i, n := range a {
  177.         if n != b[i] {
  178.             return false
  179.         }
  180.     }
  181.     return true
  182. }
  183.  
  184. // Contains takes as arguments an int slice s and an integer e.
  185. // Contains returns true if s contains e and false otherwise.
  186. func Contains(s []int, e int) bool {
  187.     for _, n := range s {
  188.         if n == e {
  189.             return true
  190.         }
  191.     }
  192.     return false
  193. }
  194.  
  195. // Hand handles an error input err.
  196. // If err is nil, Hand returns true. Otherwise, it returns false.
  197. // Hand submits a write request to the logger, containing s1 if err is nil and false otherise.
  198. func Hand(lgr *Logger, err error, s1 string, s2 string) bool {
  199.     if err != nil {
  200.         if s1 != "" {
  201.             go Write(lgr, s1 + "\n")
  202.         }
  203.         return false
  204.     }
  205.     if s2 != "" {
  206.         go Write(lgr, s2 + "\n")
  207.     }
  208.     return true
  209. }
  210.  
  211. // Inc increments the value of x.
  212. // Inc is atomic.
  213. func Inc(x *uint64) {
  214.     atomic.AddUint64(x, 1)
  215. }
  216.  
  217. // Replace takes as arguments string s, rune r, and integer i.
  218. // Replace returns a new string identical to s, except character i is replaced with r.
  219. func Replace(s string, r rune, i int) string {
  220.     ss := []rune(s)
  221.     ss[i] = r
  222.     return string(ss)
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement