-
Notifications
You must be signed in to change notification settings - Fork 2
/
papersave-block.go
106 lines (92 loc) · 2.6 KB
/
papersave-block.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright © 2020 Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>
// This program is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What The Fuck You Want
// To Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/wtfpl/COPYING for more details.
package main
import (
"bytes"
"fmt"
"io"
qrcode "github.com/skip2/go-qrcode"
)
const (
// A block consists of 8 lines
blockSize int = 8
blockChars = blockSize * lineLength
)
// A Block is part of a Share. Each block has a maximum of blockSize lines
// and blockChars characters.
type Block struct {
// Block ID within current share.
ID int
// The ShareID this blocks belongs to.
ShareID int
// block checksums.
Checksum *Checksums
// This block lines.
Lines []*Line
// The starting and ending lines of this block.
LineMin int
LineMax int
// Path to the QRCode representation of this block.
QRcode string
}
// newBlocks creates a new Blocks array of provided data.
//
// Each block has at least blockSize lines of lineLength chars (last line
// can be shorter).
func newBlocks(shareid int, data []byte) (b []*Block, err error) {
blocks := byteWrap(data, blockChars)
b = make([]*Block, len(blocks))
for i, block := range blocks {
var l []*Line
l, err = newLines(i, block)
if err != nil {
return
}
b[i] = &Block{
ID: i + 1,
ShareID: shareid,
Lines: l,
LineMin: l[0].Number,
LineMax: l[len(l)-1].Number,
}
b[i].checksum()
}
return
}
// checksum computes the block base64 checksums. For convenience the data is
// split by lines. This allows user to type the block content line by line
// in a file and chech the result using regular unix tools.
func (b *Block) checksum() (err error) {
b64chk := newChksum()
mw1 := io.MultiWriter(b64chk.Writers()...)
mw1.Write(b.B64())
b.Checksum = b64chk.Checksums()
return
}
// B64 writes a returns all block lines delimited by a NewLine. This
// function is useful to generate the block QRcode or generate the block
// checksums.
func (b *Block) B64() []byte {
var buf bytes.Buffer
for _, l := range b.Lines {
buf.Write(l.Content)
buf.Write([]byte{'\n'})
}
return buf.Bytes()
}
// GenQRCode generate a QRcode image of the current block and store it into
// te workdir directory.
func (b *Block) GenQRCode(workdir string) (err error) {
qrcodeFile := fmt.Sprintf("%s/%s", workdir, b.QRcode)
// fmt.Printf("Generating QRcode %s\n", qrcodeFile)
err = qrcode.WriteFile(
string(b.B64()),
qrcode.Low,
1024,
qrcodeFile)
return
}