go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

split.go (4852B)


      1 package render
      2 
      3 import (
      4 	"fmt"
      5 	"strings"
      6 )
      7 
      8 func bookmark(values []string) []uint32 {
      9 	var c int
     10 	var bookmarks []uint32 = []uint32{0}
     11 
     12 	for _, v := range values {
     13 		c += len(v) + 1
     14 		bookmarks = append(bookmarks, uint32(c))
     15 	}
     16 	return bookmarks
     17 }
     18 //
     19 //func paginate(bookmarks []uint32, capacity uint32) ([][]uint32, error) {
     20 //	if len(bookmarks) == 0 {
     21 //		return nil, fmt.Errorf("empty bookmark array")
     22 //	}
     23 //	var c uint32
     24 //	var pages [][]uint32
     25 //	var prev uint32
     26 //	
     27 //	pages = append(pages, []uint32{})
     28 //	currentPage := 0
     29 //	lookAhead := bookmarks[1:]
     30 //
     31 //	for i, v := range lookAhead {
     32 //		lc := v - c
     33 //		if lc > capacity {
     34 //			c = prev
     35 //			if lc - c > capacity {
     36 //				return nil, fmt.Errorf("value at %v alone exceeds capacity", i)
     37 //			}
     38 //			currentPage += 1
     39 //			pages = append(pages, []uint32{})
     40 //		}
     41 //		pages[currentPage] = append(pages[currentPage], bookmarks[i])
     42 //		prev = v
     43 //	}
     44 //
     45 //	pages[currentPage] = append(pages[currentPage], bookmarks[len(bookmarks)-1])
     46 //	return pages, nil
     47 //}
     48 
     49 func isLast(cursor uint32, end uint32, capacity uint32) bool {
     50 	l := end - cursor
     51 	remaining := capacity
     52 	return l <= remaining
     53 }
     54 
     55 func paginate(bookmarks []uint32, capacity uint32, nextSize uint32, prevSize uint32) ([][]uint32, error) {
     56 	if len(bookmarks) == 0 {
     57 		return nil, fmt.Errorf("empty page array")
     58 	}
     59 
     60 	var pages [][]uint32
     61 	var c uint32
     62 	lastIndex := len(bookmarks) - 1
     63 	last := bookmarks[lastIndex]
     64 	var haveMore bool
     65 
     66 	if isLast(0, last, capacity) {
     67 		pages = append(pages, bookmarks)
     68 		return pages, nil
     69 	}
     70 
     71 	lookAhead := bookmarks[1:]
     72 	pages = append(pages, []uint32{})
     73 	var i int
     74 
     75 	haveMore = true
     76 	for haveMore {
     77 		remaining := int(capacity)
     78 		if i > 0 {
     79 			remaining -= int(prevSize)
     80 		}
     81 		if remaining < 0 {
     82 			return nil, fmt.Errorf("underrun in item %v:%v (%v) index %v prevsize %v remain %v cap %v", bookmarks[i], lookAhead[i], lookAhead[i] - bookmarks[i], i, prevSize, remaining, capacity)
     83 		}
     84 		if isLast(c, last, uint32(remaining)) {
     85 			haveMore = false
     86 		} else {
     87 			remaining -= int(nextSize)
     88 		}
     89 		if remaining < 0 {
     90 			return nil, fmt.Errorf("underrun in item %v:%v (%v) index %v prevsize %v nextsize %v remain %v cap %v", bookmarks[i], lookAhead[i], lookAhead[i] - bookmarks[i], i, prevSize, nextSize, remaining, capacity)
     91 		}
     92 
     93 		var z int
     94 		currentPage := len(pages) - 1
     95 		for i < lastIndex {
     96 			logg.Tracef("have render", "bookmark", bookmarks[i], "lookahead", lookAhead[i], "diff", lookAhead[i] - bookmarks[i], "index", i, "prevsize", prevSize, "nextsize", nextSize, "remain", remaining, "capacity", capacity)
     97 
     98 			v := lookAhead[i]
     99 			delta := int((v - c) + 1)
    100 			if z == 0 {
    101 				if delta > remaining {
    102 					return nil, fmt.Errorf("single value at %v exceeds capacity", i)
    103 				}
    104 			}
    105 			z += delta
    106 			if z > remaining {
    107 				break
    108 			}
    109 			pages[currentPage] = append(pages[currentPage], bookmarks[i])
    110 			c = v
    111 			i += 1
    112 		}
    113 		logg.Tracef("render more", "have", haveMore, "remain", remaining, "c", c, "last", last, "pages", pages)
    114 
    115 		if haveMore {
    116 			pages = append(pages, []uint32{})
    117 		}
    118 	}
    119 
    120 	l := len(pages)-1
    121 	pages[l] = append(pages[l], last)
    122 	return pages, nil
    123 }
    124 
    125 func explode(values []string, pages [][]uint32) string {
    126 	s := strings.Join(values, "")
    127 	s += "\n"
    128 	sb := strings.Builder{}
    129 
    130 	var start uint32
    131 	var end uint32
    132 	var lastPage int
    133 	var z uint32
    134 	for i, page := range pages {
    135 		for _, c := range page {
    136 			if c == 0 {
    137 				continue
    138 			}
    139 			z += 1
    140 			if i != lastPage {
    141 				sb.WriteRune('\n')
    142 			} else if c > 0 {
    143 				sb.WriteByte(byte(0x00))
    144 			}
    145 			end = c - z
    146 			v := s[start:end]
    147 			logg.Tracef("explode", "page", i, "part start", start, "part end", end, "part str", v)
    148 			v = s[start:end]
    149 			sb.WriteString(v)
    150 			start = end
    151 		}
    152 		lastPage = i
    153 	}
    154 	r := sb.String()
    155 	r = strings.TrimRight(r, "\n")
    156 	return r
    157 }
    158 
    159 //	if lastCursor <= capacity {
    160 //		return pages, nil
    161 //	}
    162 //
    163 //	var flatPages [][]uint32 
    164 //
    165 //	pages = append(pages, []uint32{})
    166 //	for _, v := range bookmarks {
    167 //		for _, vv := range v {
    168 //			pages[0] = append(pages[0], vv)
    169 //		}
    170 //	}
    171 //
    172 //	var c uint32
    173 //	var prev uint32
    174 //	currentPage := 0 
    175 //
    176 //	for i, page := range pages {
    177 //		var delta uint32
    178 //		if i == 0 {
    179 //			delta = nextSize
    180 //		} else if i == len(pages) - 1 {
    181 //			delta = prevSize
    182 //		} else {
    183 //			delta = nextSize + prevSize
    184 //		}
    185 //		remaining := capacity - delta
    186 //		log.Printf("processing page %v", page)
    187 //		lookAhead := page[1:]
    188 //
    189 //		for j, v := range lookAhead {
    190 //			lc := v - c
    191 //			log.Printf("currentpage j %v lc %v v %v remain %v", j, lc, v, remaining)
    192 //			if lc > remaining {
    193 //				c = prev
    194 //				if lc - c > remaining {
    195 //					return nil, fmt.Errorf("value at page %v idx %v alone exceeds capacity", i, v)
    196 //				}
    197 //				currentPage += 1
    198 //				page = append(page, []uint32{})
    199 //			}
    200 //			page[currentPage] = append(page[currentPage], page[j])
    201 //			prev = v
    202 //		}
    203 //	}
    204 //	return page, nil
    205 //}