Expose bencode.Decoder.Offset
This commit is contained in:
parent
2c6b842bbf
commit
edf2495b1f
|
@ -17,7 +17,7 @@ type Decoder struct {
|
||||||
io.ByteScanner
|
io.ByteScanner
|
||||||
io.Reader
|
io.Reader
|
||||||
}
|
}
|
||||||
offset int64
|
Offset int64
|
||||||
buf bytes.Buffer
|
buf bytes.Buffer
|
||||||
key string
|
key string
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func (d *Decoder) Decode(v interface{}) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !d.parseValue(pv.Elem()) {
|
if !d.parseValue(pv.Elem()) {
|
||||||
d.throwSyntaxError(d.offset-1, errors.New("unexpected 'e'"))
|
d.throwSyntaxError(d.Offset-1, errors.New("unexpected 'e'"))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,11 @@ func checkForUnexpectedEOF(err error, offset int64) {
|
||||||
func (d *Decoder) readByte() byte {
|
func (d *Decoder) readByte() byte {
|
||||||
b, err := d.r.ReadByte()
|
b, err := d.r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
checkForUnexpectedEOF(err, d.offset)
|
checkForUnexpectedEOF(err, d.Offset)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.offset++
|
d.Offset++
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ func (d *Decoder) throwSyntaxError(offset int64, err error) {
|
||||||
|
|
||||||
// called when 'i' was consumed
|
// called when 'i' was consumed
|
||||||
func (d *Decoder) parseInt(v reflect.Value) {
|
func (d *Decoder) parseInt(v reflect.Value) {
|
||||||
start := d.offset - 1
|
start := d.Offset - 1
|
||||||
d.readUntil('e')
|
d.readUntil('e')
|
||||||
if d.buf.Len() == 0 {
|
if d.buf.Len() == 0 {
|
||||||
panic(&SyntaxError{
|
panic(&SyntaxError{
|
||||||
|
@ -139,7 +139,7 @@ func (d *Decoder) parseInt(v reflect.Value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) parseString(v reflect.Value) {
|
func (d *Decoder) parseString(v reflect.Value) {
|
||||||
start := d.offset - 1
|
start := d.Offset - 1
|
||||||
|
|
||||||
// read the string length first
|
// read the string length first
|
||||||
d.readUntil(':')
|
d.readUntil(':')
|
||||||
|
@ -148,11 +148,11 @@ func (d *Decoder) parseString(v reflect.Value) {
|
||||||
|
|
||||||
d.buf.Reset()
|
d.buf.Reset()
|
||||||
n, err := io.CopyN(&d.buf, d.r, length)
|
n, err := io.CopyN(&d.buf, d.r, length)
|
||||||
d.offset += n
|
d.Offset += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
checkForUnexpectedEOF(err, d.offset)
|
checkForUnexpectedEOF(err, d.Offset)
|
||||||
panic(&SyntaxError{
|
panic(&SyntaxError{
|
||||||
Offset: d.offset,
|
Offset: d.Offset,
|
||||||
What: errors.New("unexpected I/O error: " + err.Error()),
|
What: errors.New("unexpected I/O error: " + err.Error()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ func (d *Decoder) readOneValue() bool {
|
||||||
d.r.UnreadByte()
|
d.r.UnreadByte()
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
d.offset++
|
d.Offset++
|
||||||
d.buf.WriteByte(b)
|
d.buf.WriteByte(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,22 +359,22 @@ func (d *Decoder) readOneValue() bool {
|
||||||
start := d.buf.Len() - 1
|
start := d.buf.Len() - 1
|
||||||
d.readUntil(':')
|
d.readUntil(':')
|
||||||
length, err := strconv.ParseInt(d.buf.String()[start:], 10, 64)
|
length, err := strconv.ParseInt(d.buf.String()[start:], 10, 64)
|
||||||
checkForIntParseError(err, d.offset-1)
|
checkForIntParseError(err, d.Offset-1)
|
||||||
|
|
||||||
d.buf.WriteString(":")
|
d.buf.WriteString(":")
|
||||||
n, err := io.CopyN(&d.buf, d.r, length)
|
n, err := io.CopyN(&d.buf, d.r, length)
|
||||||
d.offset += n
|
d.Offset += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
checkForUnexpectedEOF(err, d.offset)
|
checkForUnexpectedEOF(err, d.Offset)
|
||||||
panic(&SyntaxError{
|
panic(&SyntaxError{
|
||||||
Offset: d.offset,
|
Offset: d.Offset,
|
||||||
What: errors.New("unexpected I/O error: " + err.Error()),
|
What: errors.New("unexpected I/O error: " + err.Error()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
d.raiseUnknownValueType(b, d.offset-1)
|
d.raiseUnknownValueType(b, d.Offset-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -435,7 +435,7 @@ func (d *Decoder) parseValue(v reflect.Value) bool {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
d.offset++
|
d.Offset++
|
||||||
|
|
||||||
switch b {
|
switch b {
|
||||||
case 'e':
|
case 'e':
|
||||||
|
@ -455,7 +455,7 @@ func (d *Decoder) parseValue(v reflect.Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
d.raiseUnknownValueType(b, d.offset-1)
|
d.raiseUnknownValueType(b, d.Offset-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -474,7 +474,7 @@ func (d *Decoder) parseValueInterface() (interface{}, bool) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
d.offset++
|
d.Offset++
|
||||||
|
|
||||||
switch b {
|
switch b {
|
||||||
case 'e':
|
case 'e':
|
||||||
|
@ -493,13 +493,13 @@ func (d *Decoder) parseValueInterface() (interface{}, bool) {
|
||||||
return d.parseStringInterface(), true
|
return d.parseStringInterface(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
d.raiseUnknownValueType(b, d.offset-1)
|
d.raiseUnknownValueType(b, d.Offset-1)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) parseIntInterface() (ret interface{}) {
|
func (d *Decoder) parseIntInterface() (ret interface{}) {
|
||||||
start := d.offset - 1
|
start := d.Offset - 1
|
||||||
d.readUntil('e')
|
d.readUntil('e')
|
||||||
if d.buf.Len() == 0 {
|
if d.buf.Len() == 0 {
|
||||||
panic(&SyntaxError{
|
panic(&SyntaxError{
|
||||||
|
@ -529,7 +529,7 @@ func (d *Decoder) parseIntInterface() (ret interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) parseStringInterface() interface{} {
|
func (d *Decoder) parseStringInterface() interface{} {
|
||||||
start := d.offset - 1
|
start := d.Offset - 1
|
||||||
|
|
||||||
// read the string length first
|
// read the string length first
|
||||||
d.readUntil(':')
|
d.readUntil(':')
|
||||||
|
@ -538,11 +538,11 @@ func (d *Decoder) parseStringInterface() interface{} {
|
||||||
|
|
||||||
d.buf.Reset()
|
d.buf.Reset()
|
||||||
n, err := io.CopyN(&d.buf, d.r, length)
|
n, err := io.CopyN(&d.buf, d.r, length)
|
||||||
d.offset += n
|
d.Offset += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
checkForUnexpectedEOF(err, d.offset)
|
checkForUnexpectedEOF(err, d.Offset)
|
||||||
panic(&SyntaxError{
|
panic(&SyntaxError{
|
||||||
Offset: d.offset,
|
Offset: d.Offset,
|
||||||
What: errors.New("unexpected I/O error: " + err.Error()),
|
What: errors.New("unexpected I/O error: " + err.Error()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -563,7 +563,7 @@ func (d *Decoder) parseDictInterface() interface{} {
|
||||||
key, ok := keyi.(string)
|
key, ok := keyi.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(&SyntaxError{
|
panic(&SyntaxError{
|
||||||
Offset: d.offset,
|
Offset: d.Offset,
|
||||||
What: errors.New("non-string key in a dict"),
|
What: errors.New("non-string key in a dict"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ func TestDecoderConsecutiveDicts(t *testing.T) {
|
||||||
|
|
||||||
d := NewDecoder(bb)
|
d := NewDecoder(bb)
|
||||||
assert.EqualValues(t, "d4:herp4:derped3:wat1:ke17:oh baby a triple!", bb.Bytes())
|
assert.EqualValues(t, "d4:herp4:derped3:wat1:ke17:oh baby a triple!", bb.Bytes())
|
||||||
assert.EqualValues(t, 0, d.offset)
|
assert.EqualValues(t, 0, d.Offset)
|
||||||
|
|
||||||
var m map[string]interface{}
|
var m map[string]interface{}
|
||||||
|
|
||||||
|
@ -83,17 +83,17 @@ func TestDecoderConsecutiveDicts(t *testing.T) {
|
||||||
assert.Len(t, m, 1)
|
assert.Len(t, m, 1)
|
||||||
assert.Equal(t, "derp", m["herp"])
|
assert.Equal(t, "derp", m["herp"])
|
||||||
assert.Equal(t, "d3:wat1:ke17:oh baby a triple!", bb.String())
|
assert.Equal(t, "d3:wat1:ke17:oh baby a triple!", bb.String())
|
||||||
assert.EqualValues(t, 14, d.offset)
|
assert.EqualValues(t, 14, d.Offset)
|
||||||
|
|
||||||
require.NoError(t, d.Decode(&m))
|
require.NoError(t, d.Decode(&m))
|
||||||
assert.Equal(t, "k", m["wat"])
|
assert.Equal(t, "k", m["wat"])
|
||||||
assert.Equal(t, "17:oh baby a triple!", bb.String())
|
assert.Equal(t, "17:oh baby a triple!", bb.String())
|
||||||
assert.EqualValues(t, 24, d.offset)
|
assert.EqualValues(t, 24, d.Offset)
|
||||||
|
|
||||||
var s string
|
var s string
|
||||||
require.NoError(t, d.Decode(&s))
|
require.NoError(t, d.Decode(&s))
|
||||||
assert.Equal(t, "oh baby a triple!", s)
|
assert.Equal(t, "oh baby a triple!", s)
|
||||||
assert.EqualValues(t, 44, d.offset)
|
assert.EqualValues(t, 44, d.Offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func check_error(t *testing.T, err error) {
|
func check_error(t *testing.T, err error) {
|
||||||
|
|
Loading…
Reference in New Issue