blob: 3ef9de9c7390b4be53d7b3897f4a52752ff582f2 [file] [log] [blame]
Nigel Taofcb64162020-07-10 22:49:41 +10001// Copyright 2020 The Wuffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build ignore
16
17package main
18
19// extract-cbor-rfc-7049-examples.go extracts the examples (Appendix A) from
20// RFC 7049 "Concise Binary Object Representation (CBOR)". Each example is
21// written to a separate file under a "cbor-rfc-7049-examples" directory.
22//
23// Usage:
24// go run extract-cbor-rfc-7049-examples.go < rfc7049-errata-corrected.txt
25//
26// The rfc7049-errata-corrected.txt file comes from
27// https://github.com/cbor/spec-with-errata-fixed
Nigel Tao0054a052020-07-24 22:47:39 +100028//
29// In hindsight, it would have been easier to start from
30// https://github.com/cbor/test-vectors
Nigel Taofcb64162020-07-10 22:49:41 +100031
32import (
33 "bytes"
34 "fmt"
35 "io/ioutil"
36 "os"
37)
38
39func main() {
40 if err := main1(); err != nil {
41 os.Stderr.WriteString(err.Error() + "\n")
42 os.Exit(1)
43 }
44}
45
46func main1() error {
47 src, err := readExampleTable()
48 if err != nil {
49 return err
50 }
51 if err := os.Mkdir("cbor-rfc-7049-examples", 0755); err != nil {
52 return err
53 }
54 for remaining := []byte(nil); len(src) > 0; src = remaining {
55 if i := bytes.IndexByte(src, '\n'); i >= 0 {
56 src, remaining = src[:i], src[i+1:]
57 } else {
58 remaining = nil
59 }
60 src = bytes.TrimSpace(src)
61 if (len(src) == 0) || (src[0] != '|') {
62 continue
63 }
64 if (len(src) != 69) || (src[31] != '|') || (src[68] != '|') {
65 return fmt.Errorf("main: unexpected table row: %q", string(src))
66 }
67 src = bytes.TrimSpace(src[33:68])
68 if len(src) == 0 {
69 if err := emit(); err != nil {
70 return err
71 }
72 continue
73 }
74 if (len(src) > 1) && (src[0] == '0') && (src[1] == 'x') {
75 src = src[2:]
76 }
77 for ; len(src) >= 2; src = src[2:] {
78 contents = append(contents, (unhex(src[0])<<4)|unhex(src[1]))
79 }
80 }
81 return emit()
82}
83
84var (
85 contents = []byte(nil)
86 fileNumber = 0
87)
88
89func emit() error {
90 if len(contents) == 0 {
91 return nil
92 }
93 filename := fmt.Sprintf("cbor-rfc-7049-examples/%02d.cbor", fileNumber)
94 fileNumber++
95 err := ioutil.WriteFile(filename, contents, 0644)
96 contents = nil
97 return err
98}
99
100func unhex(x uint8) uint8 {
101 if x >= 'a' {
102 return x + 10 - 'a'
103 }
104 return x - '0'
105}
106
107func readExampleTable() ([]byte, error) {
108 appendixA := []byte("Appendix A. Examples\n\n")
109 ruler := []byte("+------------------------------+------------------------------------+\n")
110
111 src, err := ioutil.ReadAll(os.Stdin)
112 if err != nil {
113 return nil, err
114 }
115 if i := bytes.Index(src, appendixA); i < 0 {
116 return nil, fmt.Errorf("main: couldn't find Appendix A")
117 } else {
118 src = src[i+len(appendixA):]
119 }
120 if i := bytes.Index(src, ruler); i < 0 {
121 return nil, fmt.Errorf("main: couldn't find ---- ruler")
122 } else {
123 src = src[i+len(ruler):]
124 }
125 if i := bytes.Index(src, ruler); i < 0 {
126 return nil, fmt.Errorf("main: couldn't find ---- ruler")
127 } else {
128 src = src[i+len(ruler):]
129 }
130 if i := bytes.Index(src, ruler); i < 0 {
131 return nil, fmt.Errorf("main: couldn't find Appendix B")
132 } else {
133 src = src[:i]
134 }
135 return bytes.TrimSpace(src), nil
136}