blob: 569a64222f5856fca0ed26443e0207d39e125cb4 [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
Nigel Tao788479d2021-08-22 10:52:51 +100015//go:build ignore
Nigel Taofcb64162020-07-10 22:49:41 +100016// +build ignore
17
18package main
19
20// extract-cbor-rfc-7049-examples.go extracts the examples (Appendix A) from
Nigel Tao1e96ef22020-07-27 22:00:28 +100021// RFC 7049 "Concise Binary Object Representation (CBOR)". If the -concat flag
22// is passed, a single CBOR array containing all of the examples are written to
23// stdout. Otherwise, each example is written to a separate file under a
24// "cbor-rfc-7049-examples" directory.
Nigel Taofcb64162020-07-10 22:49:41 +100025//
26// Usage:
27// go run extract-cbor-rfc-7049-examples.go < rfc7049-errata-corrected.txt
28//
29// The rfc7049-errata-corrected.txt file comes from
30// https://github.com/cbor/spec-with-errata-fixed
Nigel Tao0054a052020-07-24 22:47:39 +100031//
32// In hindsight, it would have been easier to start from
33// https://github.com/cbor/test-vectors
Nigel Taofcb64162020-07-10 22:49:41 +100034
35import (
36 "bytes"
Nigel Tao1e96ef22020-07-27 22:00:28 +100037 "flag"
Nigel Taofcb64162020-07-10 22:49:41 +100038 "fmt"
39 "io/ioutil"
40 "os"
41)
42
Nigel Tao1e96ef22020-07-27 22:00:28 +100043var concat = flag.Bool("concat", false, "output one monolithic CBOR file")
44
Nigel Taofcb64162020-07-10 22:49:41 +100045func main() {
46 if err := main1(); err != nil {
47 os.Stderr.WriteString(err.Error() + "\n")
48 os.Exit(1)
49 }
50}
51
52func main1() error {
53 src, err := readExampleTable()
54 if err != nil {
55 return err
56 }
Nigel Tao1e96ef22020-07-27 22:00:28 +100057 if *concat {
58 // Start of CBOR indefinite-length array.
59 os.Stdout.Write([]byte("\x9F"))
60 } else if err := os.Mkdir("cbor-rfc-7049-examples", 0755); err != nil {
Nigel Taofcb64162020-07-10 22:49:41 +100061 return err
62 }
63 for remaining := []byte(nil); len(src) > 0; src = remaining {
64 if i := bytes.IndexByte(src, '\n'); i >= 0 {
65 src, remaining = src[:i], src[i+1:]
66 } else {
67 remaining = nil
68 }
69 src = bytes.TrimSpace(src)
70 if (len(src) == 0) || (src[0] != '|') {
71 continue
72 }
73 if (len(src) != 69) || (src[31] != '|') || (src[68] != '|') {
74 return fmt.Errorf("main: unexpected table row: %q", string(src))
75 }
76 src = bytes.TrimSpace(src[33:68])
77 if len(src) == 0 {
78 if err := emit(); err != nil {
79 return err
80 }
81 continue
82 }
83 if (len(src) > 1) && (src[0] == '0') && (src[1] == 'x') {
84 src = src[2:]
85 }
86 for ; len(src) >= 2; src = src[2:] {
87 contents = append(contents, (unhex(src[0])<<4)|unhex(src[1]))
88 }
89 }
Nigel Tao1e96ef22020-07-27 22:00:28 +100090 if err := emit(); err != nil {
91 return err
92 }
93 if *concat {
94 // End of CBOR indefinite-length array.
95 os.Stdout.Write([]byte("\xFF"))
96 }
97 return nil
Nigel Taofcb64162020-07-10 22:49:41 +100098}
99
100var (
101 contents = []byte(nil)
102 fileNumber = 0
103)
104
105func emit() error {
106 if len(contents) == 0 {
107 return nil
108 }
Nigel Tao1e96ef22020-07-27 22:00:28 +1000109 if *concat {
110 os.Stdout.Write(contents)
111 contents = nil
112 return nil
113 }
Nigel Taofcb64162020-07-10 22:49:41 +1000114 filename := fmt.Sprintf("cbor-rfc-7049-examples/%02d.cbor", fileNumber)
115 fileNumber++
116 err := ioutil.WriteFile(filename, contents, 0644)
117 contents = nil
118 return err
119}
120
121func unhex(x uint8) uint8 {
122 if x >= 'a' {
123 return x + 10 - 'a'
124 }
125 return x - '0'
126}
127
128func readExampleTable() ([]byte, error) {
129 appendixA := []byte("Appendix A. Examples\n\n")
130 ruler := []byte("+------------------------------+------------------------------------+\n")
131
132 src, err := ioutil.ReadAll(os.Stdin)
133 if err != nil {
134 return nil, err
135 }
136 if i := bytes.Index(src, appendixA); i < 0 {
137 return nil, fmt.Errorf("main: couldn't find Appendix A")
138 } else {
139 src = src[i+len(appendixA):]
140 }
141 if i := bytes.Index(src, ruler); i < 0 {
142 return nil, fmt.Errorf("main: couldn't find ---- ruler")
143 } else {
144 src = src[i+len(ruler):]
145 }
146 if i := bytes.Index(src, ruler); i < 0 {
147 return nil, fmt.Errorf("main: couldn't find ---- ruler")
148 } else {
149 src = src[i+len(ruler):]
150 }
151 if i := bytes.Index(src, ruler); i < 0 {
152 return nil, fmt.Errorf("main: couldn't find Appendix B")
153 } else {
154 src = src[:i]
155 }
156 return bytes.TrimSpace(src), nil
157}