go-vise

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

split.go (4787B)


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