diff --git a/aper.go b/aper.go index 34b83b5..ef49007 100644 --- a/aper.go +++ b/aper.go @@ -177,6 +177,40 @@ func (pd *perBitData) parseConstraintValue(valueRange int64) (value uint64, err return value, err } +func (pd *perBitData) parseSemiConstrainedWholeNumber(lb uint64) (value uint64, err error) { + var repeat bool + var length uint64 + if length, err = pd.parseLength(-1, &repeat); err != nil { + return + } + if length > 8 || repeat { + err = fmt.Errorf("Too long length: %d", length) + return + } + if value, err = pd.getBitsValue(uint(length) * 8); err != nil { + return + } + value += lb + return +} + +func (pd *perBitData) parseNormallySmallNonNegativeWholeNumber() (value uint64, err error) { + var notSmallFlag uint64 + if notSmallFlag, err = pd.getBitsValue(1); err != nil { + return + } + if notSmallFlag == 1 { + if value, err = pd.parseSemiConstrainedWholeNumber(0); err != nil { + return + } + } else { + if value, err = pd.getBitsValue(6); err != nil { + return + } + } + return +} + func (pd *perBitData) parseLength(sizeRange int64, repeat *bool) (value uint64, err error) { *repeat = false if sizeRange <= 65536 && sizeRange > 0 { @@ -479,22 +513,30 @@ func (pd *perBitData) parseInteger(extensed bool, lowerBoundPtr *int64, upperBou } } -// parse ENUMERATED type but do not implement extensive value and different value with index func (pd *perBitData) parseEnumerated(extensed bool, lowerBoundPtr *int64, upperBoundPtr *int64) (value uint64, err error) { - if extensed { - err = fmt.Errorf("Unsupport the extensive value of ENUMERATED ") - return - } if lowerBoundPtr == nil || upperBoundPtr == nil { - err = fmt.Errorf("ENUMERATED value constraint is error ") + err = fmt.Errorf("ENUMERATED value constraint is error") return } lb, ub := *lowerBoundPtr, *upperBoundPtr - valueRange := ub - lb + 1 - perTrace(2, fmt.Sprintf("Decoding ENUMERATED with Value Range(%d..%d)", lb, ub)) - if valueRange > 1 { - value, err = pd.parseConstraintValue(valueRange) + if lb < 0 || lb > ub { + err = fmt.Errorf("ENUMERATED value constraint is error") + return + } + + if extensed { + perTrace(2, fmt.Sprintf("Decoding ENUMERATED with Extensive Value of Range(%d..)", ub+1)) + if value, err = pd.parseNormallySmallNonNegativeWholeNumber(); err != nil { + return + } + value += uint64(ub) + 1 + } else { + perTrace(2, fmt.Sprintf("Decoding ENUMERATED with Value Range(%d..%d)", lb, ub)) + valueRange := ub - lb + 1 + if valueRange > 1 { + value, err = pd.parseConstraintValue(valueRange) + } } perTrace(2, fmt.Sprintf("Decoded ENUMERATED Value : %d", value)) return diff --git a/marshal.go b/marshal.go index 1312323..4ffdf17 100644 --- a/marshal.go +++ b/marshal.go @@ -119,6 +119,40 @@ func (pd *perRawBitData) appendConstraintValue(valueRange int64, value uint64) ( return } +func (pd *perRawBitData) appendNormallySmallNonNegativeValue(value uint64) (err error) { + perTrace(3, fmt.Sprintf("Putting Normally Small Non-Negative Value %d", value)) + + if value < 64 { + if err = pd.putBitsValue(0, 1); err != nil { + return err + } + err = pd.putBitsValue(value, 6) + } else { + if err = pd.putBitsValue(1, 1); err != nil { + return err + } + err = pd.putSemiConstrainedWholeNumber(value, 0) + } + return +} + +func (pd *perRawBitData) putSemiConstrainedWholeNumber(value uint64, lb uint64) (err error) { + if lb > value { + err = fmt.Errorf("Value(%d) is less than lower bound value(%d)", value, lb) + return + } + value -= lb + var length uint64 = 1 + var valueTmp = value >> 8 + for valueTmp > 0 { + length++ + valueTmp = valueTmp >> 8 + } + pd.appendLength(-1, length) + pd.putBitsValue(value, uint(length)*8) + return +} + func (pd *perRawBitData) appendLength(sizeRange int64, value uint64) (err error) { if sizeRange <= 65536 && sizeRange > 0 { return pd.appendConstraintValue(sizeRange, value) @@ -439,33 +473,37 @@ func (pd *perRawBitData) appendInteger(value int64, extensive bool, lowerBoundPt } } -// append ENUMERATED type but do not implement extensive value and different value with index func (pd *perRawBitData) appendEnumerated(value uint64, extensive bool, lowerBoundPtr *int64, upperBoundPtr *int64) error { if lowerBoundPtr == nil || upperBoundPtr == nil { return fmt.Errorf("ENUMERATED value constraint is error") } lb, ub := *lowerBoundPtr, *upperBoundPtr - if signedValue := int64(value); signedValue > ub { + if lb < 0 || lb > ub { + return fmt.Errorf("ENUMERATED value constraint is error") + } + + if value <= uint64(ub) { if extensive { - return fmt.Errorf("Unsupport the extensive value of ENUMERATED") - } else { + if err := pd.putBitsValue(0, 1); err != nil { + return err + } + } + valueRange := ub - lb + 1 + perTrace(2, fmt.Sprintf("Encoding ENUMERATED Value : %d with Value Range(%d..%d)", value, lb, ub)) + if valueRange > 1 { + return pd.appendConstraintValue(valueRange, value) + } + } else { + if !extensive { return fmt.Errorf("ENUMERATED value is larger than upperbound") } - } else if signedValue < lb { - return fmt.Errorf("ENUMERATED value is smaller than lowerbound") - } - if extensive { - if err := pd.putBitsValue(0, 1); err != nil { + if err := pd.putBitsValue(1, 1); err != nil { return err } + return pd.appendNormallySmallNonNegativeValue(value - uint64(ub) - 1) } - valueRange := ub - lb + 1 - perTrace(2, fmt.Sprintf("Encoding ENUMERATED Value : %d with Value Range(%d..%d)", value, lb, ub)) - if valueRange > 1 { - return pd.appendConstraintValue(valueRange, value) - } return nil }