github.com/viant/toolbox@v0.34.5/text.go (about) 1 package toolbox 2 3 import ( 4 "bufio" 5 "github.com/viant/toolbox/format" 6 "io" 7 "unicode" 8 ) 9 10 //IsASCIIText return true if supplied string does not have binary data 11 func IsASCIIText(candidate string) bool { 12 for _, r := range candidate { 13 if r == '\n' || r == '\r' || r == '\t' { 14 continue 15 } 16 if r > unicode.MaxASCII || !unicode.IsPrint(r) || r == '`' { 17 return false 18 } 19 } 20 return true 21 } 22 23 //IsPrintText return true if all candidate characters are printable (unicode.IsPrintText) 24 func IsPrintText(candidate string) bool { 25 for _, r := range candidate { 26 if !unicode.IsPrint(r) { 27 if r == '\n' || r == '\r' || r == '\t' || r == '`' { 28 continue 29 } 30 return false 31 } 32 } 33 return true 34 } 35 36 //TerminatedSplitN split supplied text into n fragmentCount, each terminated with supplied terminator 37 func TerminatedSplitN(text string, fragmentCount int, terminator string) []string { 38 var result = make([]string, 0) 39 if fragmentCount == 0 { 40 fragmentCount = 1 41 } 42 fragmentSize := len(text) / fragmentCount 43 lowerBound := 0 44 for i := fragmentSize - 1; i < len(text); i++ { 45 isLast := i+1 == len(text) 46 isAtLeastOfFragmentSize := i-lowerBound >= fragmentSize 47 isNewLine := string(text[i:i+len(terminator)]) == terminator 48 if (isAtLeastOfFragmentSize && isNewLine) || isLast { 49 result = append(result, string(text[lowerBound:i+1])) 50 lowerBound = i + 1 51 } 52 } 53 return result 54 } 55 56 //SplitTextStream divides reader supplied text by number of specified line 57 func SplitTextStream(reader io.Reader, writerProvider func() io.WriteCloser, elementCount int) error { 58 scanner := bufio.NewScanner(reader) 59 var writer io.WriteCloser 60 counter := 0 61 var err error 62 if elementCount == 0 { 63 elementCount = 1 64 } 65 for scanner.Scan() { 66 67 if writer == nil { 68 writer = writerProvider() 69 } 70 data := scanner.Bytes() 71 if err = scanner.Err(); err != nil { 72 return err 73 } 74 75 if counter > 0 { 76 if _, err = writer.Write([]byte{'\n'}); err != nil { 77 return err 78 } 79 } 80 if _, err = writer.Write(data); err != nil { 81 return err 82 } 83 counter++ 84 if counter == elementCount { 85 if err := writer.Close(); err != nil { 86 return err 87 } 88 counter = 0 89 writer = nil 90 } 91 } 92 if writer != nil { 93 return writer.Close() 94 } 95 return nil 96 } 97 98 const ( 99 CaseUpper = iota 100 CaseLower 101 CaseUpperCamel 102 CaseLowerCamel 103 CaseUpperUnderscore 104 CaseLowerUnderscore 105 ) 106 107 //ToCaseFormat format text, from, to are const: CaseLower, CaseUpperCamel, CaseLowerCamel, CaseUpperUnderscore, CaseLowerUnderscore, 108 // Deprecated: please use format.Case instead 109 func ToCaseFormat(text string, from, to int) string { 110 return format.Case(from).Format(text, format.Case(to)) 111 }