C
Join ServerC#
help
Calculating length of a Span of bytes when encoding text [Answered]
BBecquerel9/7/2022
I need a method that takes text, encodes it and converts it to base 64 without allocations (if possible).
This is what I have so far:
I'm using this to encode/decode JSON. I have a unit test for roundtripping (encode/decode the same object and check it's equivalent) this that is failing.
It decodes the actual JSON correctly, but then continues onwards, filling up the string with garbage data that causes deserialization to explode.
This is what I have so far:
private Span<char> ToBase64(Span<char> text)
{
// _encoding is UTF-8
// get how many bytes the text will take up when encoded
var byteCount = _encoding.GetByteCount(text);
// alloc array with that count so we can get a Span<byte>
Span<byte> span = stackalloc byte[byteCount];
// write the encoded text into the byte span
_ = _encoding.GetBytes(text, span);
// use the encoded byte span to actually go to base64
// _encoder is a nuget package that asks for an ArraySegment<char>
return _encoder.ToBaseNonAlloc(span.ToArray());
}
I'm using this to encode/decode JSON. I have a unit test for roundtripping (encode/decode the same object and check it's equivalent) this that is failing.
private class MyObject
{
public string Name { get; set; }
public int Age { get; set; }
public bool Alive { get; set; }
}
[Fact]
public void Encode_ShouldRoundTrip()
{
var obj = new MyObject
{
Name = "John Doe",
Age = 32,
Alive = true
};
var json = JsonConvert.SerializeObject(obj);
// _encoder here is my own class where the above method lives
var encoded = _encoder.Encode(json);
var unencoded = _encoder.Decode(encoded);
var newObj = JsonConvert.DeserializeObject<MyObject>(unencoded);
newObj.Should().BeEquivalentTo(obj);
}
It decodes the actual JSON correctly, but then continues onwards, filling up the string with garbage data that causes deserialization to explode.
{"Name":"John Doe","Age":32,"Alive":truep4��bY,P�&��4]�!�V��!�]D��aQ<@0XbUh2VaplSHNXUThGbhhUTwQQP==
BBecquerel9/7/2022
My assumption is that I'm messing up how big the
Span<byte>
should be and that's causing it to include garbage data, but I don't see what I'm doing wrong.BBecquerel9/7/2022
I am doing other stuff besides just encoding the JSON that I can explain if all of that looks OK, but wanted to check this first since I've not messed with spans before.
MMKP9/7/2022
check the Span<byte>'s [length] to make sure its null terminated
BBecquerel9/7/2022
doesn't appear so

BBecquerel9/7/2022
should I set its length to byteCount + 1 and ensure the last element is
null
?MMKP9/7/2022
yeah
BBecquerel9/7/2022
what's the correct syntax for that -
span[^1] = null;
complains that I can't assign null to byteBBecquerel9/7/2022
or is it fine for it to be a
Span<byte?>
?MMKP9/7/2022
0
BBecquerel9/7/2022
ah, got you - makes sense
BBecquerel9/7/2022
tried that and i'm still getting garbage data added in so i think i need to check the rest of my implementation
BBecquerel9/7/2022
figured it out, in my method where I parsed the base64, I was writing back into the same span<char> I was reading from 😄
MMKP9/7/2022
do /close
BBecquerel9/7/2022
mhmm
AAccord9/7/2022
✅ This post has been marked as answered!