forked from CycloneDX/cyclonedx-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
encode.go
132 lines (109 loc) · 3.41 KB
/
encode.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// This file is part of CycloneDX Go
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) OWASP Foundation. All Rights Reserved.
package cyclonedx
import (
"encoding/json"
"encoding/xml"
"fmt"
"io"
)
type BOMEncoder interface {
// Encode encodes a given BOM.
Encode(bom *BOM) error
// EncodeVersion encodes a given BOM in a specific version of the specification.
// Choosing a lower spec version than what the BOM was constructed for will result
// in loss of information. The original BOM struct is guaranteed to not be modified.
EncodeVersion(bom *BOM, version SpecVersion) error
// SetPretty toggles prettified output.
SetPretty(pretty bool) BOMEncoder
// SetEscapeHTML toggles escaped HTML output.
SetEscapeHTML(escapeHTML bool) BOMEncoder
}
func NewBOMEncoder(writer io.Writer, format BOMFileFormat) BOMEncoder {
if format == BOMFileFormatJSON {
return &jsonBOMEncoder{writer: writer, escapeHTML: true}
}
return &xmlBOMEncoder{writer: writer}
}
type jsonBOMEncoder struct {
writer io.Writer
pretty bool
escapeHTML bool
}
// Encode implements the BOMEncoder interface.
func (j jsonBOMEncoder) Encode(bom *BOM) error {
if bom.SpecVersion < SpecVersion1_2 {
return fmt.Errorf("json format is not supported for specification versions lower than %s", SpecVersion1_2)
}
encoder := json.NewEncoder(j.writer)
encoder.SetEscapeHTML(j.escapeHTML)
if j.pretty {
encoder.SetIndent("", " ")
}
return encoder.Encode(bom)
}
// EncodeVersion implements the BOMEncoder interface.
func (j jsonBOMEncoder) EncodeVersion(bom *BOM, specVersion SpecVersion) (err error) {
bom, err = bom.copyAndConvert(specVersion)
if err != nil {
return
}
return j.Encode(bom)
}
// SetPretty implements the BOMEncoder interface.
func (j *jsonBOMEncoder) SetPretty(pretty bool) BOMEncoder {
j.pretty = pretty
return j
}
// SetEscapeHTML implements the BOMEncoder interface.
func (j *jsonBOMEncoder) SetEscapeHTML(escapeHTML bool) BOMEncoder {
j.escapeHTML = escapeHTML
return j
}
type xmlBOMEncoder struct {
writer io.Writer
pretty bool
}
// Encode implements the BOMEncoder interface.
func (x xmlBOMEncoder) Encode(bom *BOM) error {
if _, err := fmt.Fprintf(x.writer, xml.Header); err != nil {
return err
}
encoder := xml.NewEncoder(x.writer)
if x.pretty {
encoder.Indent("", " ")
}
return encoder.Encode(bom)
}
// EncodeVersion implements the BOMEncoder interface.
func (x xmlBOMEncoder) EncodeVersion(bom *BOM, specVersion SpecVersion) (err error) {
bom, err = bom.copyAndConvert(specVersion)
if err != nil {
return
}
return x.Encode(bom)
}
// SetPretty implements the BOMEncoder interface.
func (x *xmlBOMEncoder) SetPretty(pretty bool) BOMEncoder {
x.pretty = pretty
return x
}
// SetEscapeHTML implements the BOMEncoder interface.
func (j *xmlBOMEncoder) SetEscapeHTML(escapeHTML bool) BOMEncoder {
// NOOP -- XML always needs to escape HTML
return j
}