Closed v-almonacid closed 4 years ago
What would you think about having stream.Readable's encoded indefinitely, with either an Array (if the stream is in object mode) or a byte string (if not in object mode). I can't think of how to cause indefinite maps or indefinite strings, but neither of those have interesting use cases that I can think of.
Once I get something working for the above, I bet something will become apparent for those cases if someone wants them.
It sounds good to me but honestly I don't know much about how things are implemented.
I need to encode a rather simple data structure of the form: x = [ [ [ [Array], [Array] ], [ [Array] ] ] ]
. Right now it works almost perfectly just using cbor.encode(x)
, the only detail is that a few arrays within x
need to be 9F...FF
I figured out a work-around for you:
function encodeArrayIndefinite(gen, obj) {
if (obj == null) {
obj = this
}
let ret = gen.push(Buffer.from([0x9f])) // indefinite array
for (const e of obj) {
ret = ret && gen.pushAny(e)
}
ret = ret && gen.push(Buffer.from([0xff])) // done
return ret
}
const bytes = cbor.encodeOne([1, "a", false, Infinity, []], {
genTypes: [
Array, encodeArrayIndefinite
]
})
If you only want to encode some arrays that way, you could do this:
const a = [1, "a", false, Infinity, []]
a.encodeCBOR = encodeArrayIndefinite
I figured out a work-around for you:
function encodeArrayIndefinite(gen, obj) { if (obj == null) { obj = this } let ret = gen.push(Buffer.from([0x9f])) // indefinite array for (const e of obj) { ret = ret && gen.pushAny(e) } ret = ret && gen.push(Buffer.from([0xff])) // done return ret } const bytes = cbor.encodeOne([1, "a", false, Infinity, []], { genTypes: [ Array, encodeArrayIndefinite ] })
can you please also help with a workaround to encode an indefinite map as well!!
I figured out a work-around for you:
function encodeArrayIndefinite(gen, obj) { if (obj == null) { obj = this } let ret = gen.push(Buffer.from([0x9f])) // indefinite array for (const e of obj) { ret = ret && gen.pushAny(e) } ret = ret && gen.push(Buffer.from([0xff])) // done return ret } const bytes = cbor.encodeOne([1, "a", false, Infinity, []], { genTypes: [ Array, encodeArrayIndefinite ] })
I really appreciate that you took the time to look into it, thanks! I ended up just using an ugly hack, but your workaround looks much better.
I've added Encoder.encodeIndefinite
with an example in the docs. Should work for Array, Map, String, Buffer, and Objects. I'm going to fix a thing or too more before doing a release, hopefully in a few hours, but take a look at the tests in the above commit for some ideas on how to use it.
cbor.Encoder.encodeIndefinite returns undefined
I think I haven't done a release with encodeIndefinite in it. I'll get on that in the next day or two.
It would be great that you will do a new release with the indefinite lengths for the array and map.
Sorry, I finally got around to a release. Try 5.1.1, and file new bugs as needed.
Is is possible to enforce the encoder to use indefinite-length arrays?
What I want to achieve is for instance:
and after encoding, obtain:
Note that the outer array has indefinite-length while the inner array has a fixed length.