go-vise

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

split.go (4846B)


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