Skip to content

Commit

Permalink
Improve code according to fxamacker' review.
Browse files Browse the repository at this point in the history
Signed-off-by: Yan Qing <[email protected]>
  • Loading branch information
zensh committed May 1, 2023
1 parent 1eed832 commit a1c3064
Showing 1 changed file with 69 additions and 72 deletions.
141 changes: 69 additions & 72 deletions diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,49 +114,45 @@ func (opts DiagOptions) diagMode() (*diagMode, error) {
return nil, err
}

return &diagMode{&opts, decMode}, nil
return &diagMode{
byteStringEncoding: opts.ByteStringEncoding,
byteStringHexWhitespace: opts.ByteStringHexWhitespace,
byteStringText: opts.ByteStringText,
byteStringEmbeddedCBOR: opts.ByteStringEmbeddedCBOR,
cborSequence: opts.CBORSequence,
indicateFloatPrecision: opts.IndicateFloatPrecision,
decMode: decMode,
}, nil
}

type diagMode struct {
opts *DiagOptions
decMode *decMode
byteStringEncoding ByteStringEncoding
byteStringHexWhitespace bool
byteStringText bool
byteStringEmbeddedCBOR bool
cborSequence bool
indicateFloatPrecision bool
decMode *decMode
}

// DiagOptions returns user specified options used to create this DiagMode.
func (dm *diagMode) DiagOptions() DiagOptions {
return *dm.opts
return DiagOptions{
ByteStringEncoding: dm.byteStringEncoding,
ByteStringHexWhitespace: dm.byteStringHexWhitespace,
ByteStringText: dm.byteStringText,
ByteStringEmbeddedCBOR: dm.byteStringEmbeddedCBOR,
CBORSequence: dm.cborSequence,
IndicateFloatPrecision: dm.indicateFloatPrecision,
MaxNestedLevels: dm.decMode.maxNestedLevels,
MaxArrayElements: dm.decMode.maxArrayElements,
MaxMapPairs: dm.decMode.maxMapPairs,
}
}

// Diagnose returns extended diagnostic notation (EDN) of CBOR data items using the DiagMode.
func (dm *diagMode) Diagnose(data []byte) (string, error) {
di, err := dm.diagnose(data)
if err != nil {
return "", err
}

return di.diag()
}

func (dm *diagMode) diagnose(data []byte) (*diagnose, error) {
de := &decoder{data: data, dm: dm.decMode}
off := de.off
err := de.valid(dm.opts.CBORSequence)
de.off = off
if err != nil {
return nil, err
}

di := &diagnose{
byteStringEncoding: dm.opts.ByteStringEncoding,
byteStringHexWhitespace: dm.opts.ByteStringHexWhitespace,
byteStringText: dm.opts.ByteStringText,
byteStringEmbeddedCBOR: dm.opts.ByteStringEmbeddedCBOR,
cborSequence: dm.opts.CBORSequence,
indicateFloatPrecision: dm.opts.IndicateFloatPrecision,

dm: dm, d: de, w: &bytes.Buffer{},
}
return di, nil
return newDiagnose(data, dm.decMode, dm).diag()
}

var defaultDiagMode, _ = DiagOptions{}.diagMode()
Expand All @@ -170,30 +166,32 @@ func Diagnose(data []byte) (string, error) {
}

type diagnose struct {
byteStringEncoding ByteStringEncoding
byteStringHexWhitespace bool
byteStringText bool
byteStringEmbeddedCBOR bool
cborSequence bool
indicateFloatPrecision bool
dm *diagMode
d *decoder
w *bytes.Buffer
dm *diagMode
d *decoder
w *bytes.Buffer
}

func (di *diagnose) diag() (string, error) {
if err := di.value(); err != nil {
return "", err
func newDiagnose(data []byte, decm *decMode, diagm *diagMode) *diagnose {
return &diagnose{
dm: diagm,
d: &decoder{data: data, dm: decm},
w: &bytes.Buffer{},
}
}

func (di *diagnose) diag() (string, error) {
// CBOR Sequence
firstItem := true
for {
switch err := di.valid(); err {
case nil:
if err = di.writeString(", "); err != nil {
return di.w.String(), err
if !firstItem {
if err = di.writeString(", "); err != nil {
return di.w.String(), err
}
}
if err = di.value(); err != nil {
firstItem = false
if err = di.item(); err != nil {
return di.w.String(), err
}

Expand All @@ -208,12 +206,12 @@ func (di *diagnose) diag() (string, error) {

func (di *diagnose) valid() error {
off := di.d.off
err := di.d.valid(di.cborSequence)
err := di.d.valid(di.dm.cborSequence)
di.d.off = off
return err
}

func (di *diagnose) value() error { //nolint:gocyclo
func (di *diagnose) item() error { //nolint:gocyclo
initialByte := di.d.data[di.d.off]
switch initialByte {
case 0x5f, 0x7f: // indefinite byte string or UTF-8 text
Expand All @@ -231,7 +229,7 @@ func (di *diagnose) value() error { //nolint:gocyclo
}

i++
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
}
Expand All @@ -253,7 +251,7 @@ func (di *diagnose) value() error { //nolint:gocyclo
}

i++
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
}
Expand All @@ -276,7 +274,7 @@ func (di *diagnose) value() error { //nolint:gocyclo

i++
// key
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}

Expand All @@ -285,7 +283,7 @@ func (di *diagnose) value() error { //nolint:gocyclo
}

// value
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
}
Expand Down Expand Up @@ -337,7 +335,7 @@ func (di *diagnose) value() error { //nolint:gocyclo
return err
}
}
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
}
Expand All @@ -357,14 +355,14 @@ func (di *diagnose) value() error { //nolint:gocyclo
}
}
// key
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
if err := di.writeString(": "); err != nil {
return err
}
// value
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
}
Expand Down Expand Up @@ -392,7 +390,7 @@ func (di *diagnose) value() error { //nolint:gocyclo
if err := di.writeByte('('); err != nil {
return err
}
if err := di.value(); err != nil {
if err := di.item(); err != nil {
return err
}
return di.writeByte(')')
Expand Down Expand Up @@ -455,33 +453,32 @@ var rawBase32HexEncoding = base32.HexEncoding.WithPadding(base32.NoPadding)

func (di *diagnose) encodeByteString(val []byte) error {
if len(val) > 0 {
if di.byteStringText && utf8.Valid(val) {
if di.dm.byteStringText && utf8.Valid(val) {
return di.encodeTextString(string(val), '\'')
}

if di.byteStringEmbeddedCBOR {
if di2, err := di.dm.diagnose(val); err == nil {
if str, err := di2.diag(); err == nil {
if err := di.writeString("<<"); err != nil {
return err
}
if err := di.writeString(str); err != nil {
return err
}
return di.writeString(">>")
if di.dm.byteStringEmbeddedCBOR {
di2 := newDiagnose(val, di.dm.decMode, di.dm)
if str, err := di2.diag(); err == nil {
if err := di.writeString("<<"); err != nil {
return err
}
if err := di.writeString(str); err != nil {
return err
}
return di.writeString(">>")
}
}
}

switch di.byteStringEncoding {
switch di.dm.byteStringEncoding {
case ByteStringBase16Encoding:
if err := di.writeString("h'"); err != nil {
return err
}

encoder := hex.NewEncoder(di.w)
if di.byteStringHexWhitespace {
if di.dm.byteStringHexWhitespace {
for i, b := range val {
if i > 0 {
if err := di.writeByte(' '); err != nil {
Expand Down Expand Up @@ -533,7 +530,7 @@ func (di *diagnose) encodeByteString(val []byte) error {
return di.writeByte('\'')

default:
return di.byteStringEncoding.valid()
return di.dm.byteStringEncoding.valid()
}
}

Expand Down Expand Up @@ -681,7 +678,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error {
return err
}

if di.indicateFloatPrecision {
if di.dm.indicateFloatPrecision {
switch ai {
case 25:
return di.writeString("_1")
Expand Down

0 comments on commit a1c3064

Please sign in to comment.