Skip to content

Commit 106fc3c

Browse files
committed
Fixed #59
1 parent a97e95c commit 106fc3c

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

dist/types/recursive.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,31 @@ class RecursiveType extends absolute_1.default {
158158
*/
159159
writeValue(buffer, value) {
160160
this.isBuffer(buffer);
161-
let writeValue = true;
162161
let bufferRecursiveLocations = recursiveLocations.get(buffer);
163162
if (bufferRecursiveLocations) {
164163
const targetLocation = bufferRecursiveLocations.get(value);
165164
if (targetLocation !== undefined) {
166-
writeValue = false;
167165
buffer.add(0x00);
168166
const offset = buffer.length - targetLocation; //calculate offset to previous location
169167
buffer.addAll(flexInt.makeValueBuffer(offset));
168+
return;
170169
}
171170
}
172171
else {
173172
bufferRecursiveLocations = new Map;
174173
recursiveLocations.set(buffer, bufferRecursiveLocations);
175174
}
176-
if (writeValue) {
177-
buffer.add(0xFF);
178-
//Keep track of the location before writing the data so that this location can be referenced by sub-values
179-
bufferRecursiveLocations.set(value, buffer.length);
175+
//Value has not yet been written to the buffer
176+
buffer.add(0xFF);
177+
//Keep track of the location before writing the data so that this location can be referenced by sub-values
178+
bufferRecursiveLocations.set(value, buffer.length);
179+
try {
180180
this.type.writeValue(buffer, value);
181181
}
182+
catch (e) {
183+
bufferRecursiveLocations.delete(value);
184+
throw e;
185+
}
182186
}
183187
consumeValue(buffer, offset) {
184188
const explicit = read_util_1.readBooleanByte(buffer, offset);

test/value-bytes/recursive.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import * as rec from '../../dist'
44
import * as t from '../../dist'
55
import {bufferFrom} from '../test-common'
66

7+
type Field = {a: Fields} | {b: boolean}
8+
interface Fields {
9+
fields: Field[]
10+
}
11+
712
export = () => {
813
interface GraphNode {
914
links: Set<GraphNode>
@@ -221,6 +226,30 @@ export = () => {
221226
0x00, 12
222227
]))
223228

229+
{
230+
const fieldsType = new t.RecursiveType<Fields>('fields')
231+
rec.registerType({
232+
type: new t.StructType({
233+
fields: new t.ArrayType(
234+
new t.ChoiceType<Field>([
235+
new t.StructType({a: fieldsType}),
236+
new t.StructType({b: new t.BooleanType})
237+
])
238+
)
239+
}),
240+
name: 'fields'
241+
})
242+
assert.throws(
243+
() => fieldsType.valueBuffer({
244+
fields: [
245+
{a: null as any, b: true}, //this will try to write null with fieldsType
246+
{a: null as any, b: 1 as any} //ensure null is not considered already written by fieldsType
247+
]
248+
}),
249+
'No types matched: {a: null, b: 1}'
250+
)
251+
}
252+
224253
assert.throws(
225254
() => selfReferenceType.readValue(bufferFrom([0xff, 0x00, 2])),
226255
'Cannot find target at 0'

types/recursive.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,26 +165,29 @@ export default class RecursiveType<E, READ_E extends E = E> extends AbsoluteType
165165
*/
166166
writeValue(buffer: AppendableBuffer, value: E) {
167167
this.isBuffer(buffer)
168-
let writeValue = true
169168
let bufferRecursiveLocations = recursiveLocations.get(buffer)
170169
if (bufferRecursiveLocations) {
171170
const targetLocation = bufferRecursiveLocations.get(value)
172171
if (targetLocation !== undefined) { //value has already been written to the buffer
173-
writeValue = false
174172
buffer.add(0x00)
175173
const offset = buffer.length - targetLocation //calculate offset to previous location
176174
buffer.addAll(flexInt.makeValueBuffer(offset))
175+
return
177176
}
178177
}
179178
else {
180179
bufferRecursiveLocations = new Map
181180
recursiveLocations.set(buffer, bufferRecursiveLocations)
182181
}
183-
if (writeValue) { //value has not yet been written to the buffer
184-
buffer.add(0xFF)
185-
//Keep track of the location before writing the data so that this location can be referenced by sub-values
186-
bufferRecursiveLocations.set(value, buffer.length)
187-
this.type.writeValue(buffer, value)
182+
183+
//Value has not yet been written to the buffer
184+
buffer.add(0xFF)
185+
//Keep track of the location before writing the data so that this location can be referenced by sub-values
186+
bufferRecursiveLocations.set(value, buffer.length)
187+
try { this.type.writeValue(buffer, value) }
188+
catch (e) {
189+
bufferRecursiveLocations.delete(value)
190+
throw e
188191
}
189192
}
190193
consumeValue(buffer: ArrayBuffer, offset: number): ReadResult<READ_E> {

0 commit comments

Comments
 (0)