1) A "varint" is a "variable length integer". When you replace a large 
number with a small one, it's entirely possible to lose some bytes and 
still be valid. You need to check the actual output.

2) Can you provide the proto definition of the field you want to modify? 
Scalar fields get set to the last encountered value, so the easiest option 
may be to copy the original bytes and append a delta containing the 
differences.
 



On Wednesday, September 20, 2023 at 10:19:07 AM UTC+2 Joan Balagueró wrote:

> Hello,
>
> I have a protobuf message like this into a byte array:
>
>         1: { // META element
>             1: 2
>             2: 1
>             3: 1
>             4: {            // CutOffTime element within META
>                 1: 10
>                 2: 3
>                }
>             5: 1
>             6: 40
>         }
>         2: 9836 // HOTEL element
>         3: 724 // MARKET element
>
>
> We need to traverse this message and write it to a 'CodeOutputStream', but 
> changing the values of the 'cutoff' element to, for example to '4: { 1: 7, 
> 2: 4 }'. I'm not able to do it, I need some help.
>
> A basic algorithm that writes the same protobuf to another byte array but 
> without changing anything works. Here I try the special case of 'META' (key 
> = 1) that contains the 'cutoff' element.
>
> Map<Integer, UnknownFieldSet.Field> rootFields = 
> UnknownFieldSet.parseFrom(document).asMap();
>
>             for (Map.Entry<Integer, UnknownFieldSet.Field> entry : 
> rootFields.entrySet()) {
>                 if (entry.getKey() == 1) {
>                     ByteString bs = 
> entry.getValue().getLengthDelimitedList().get(0);
>                     output.writeByteArray(1, bs.toByteArray());
>                 }
>                 else {
>                     entry.getValue().writeTo(entry.getKey(), output);
>                 }
>             }
>
>
> Now I try to go a bit further, trying to read the cuotff element, change 
> the values and rewrite them to the 'output'. And here is when I'm not able 
> to solve the problem. Below my try that does not work, it generates a byte 
> array
> of 69 bytes instead of 73 (I'm losing 4 bytes):
>
> Map<Integer, UnknownFieldSet.Field> rootFields = 
> UnknownFieldSet.parseFrom(document).asMap();
>             
> for (Map.Entry<Integer, UnknownFieldSet.Field> entry : 
> rootFields.entrySet()) {
>                 if (entry.getKey() == 1) {
>                     ByteString bs = 
> entry.getValue().getLengthDelimitedList().get(0);
>                     Map<Integer, UnknownFieldSet.Field> ufs = 
> UnknownFieldSet.parseFrom(bs).asMap();
>
>                     for (Map.Entry<Integer, UnknownFieldSet.Field> item : 
> ufs.entrySet()) {
>                         if (item.getKey() == 4) {
>                             Map<Integer, UnknownFieldSet.Field> cutoff = 
> UnknownFieldSet.parseFrom(item.getValue().getLengthDelimitedList().get(0)).asMap();
>                             cutoff.put(1, 
> UnknownFieldSet.Field.newBuilder().addVarint(7).build()).writeTo(1, output);
>                             cutoff.put(2, 
> UnknownFieldSet.Field.newBuilder().addVarint(4).build()).writeTo(1, output);
>                         }
>                         else {
>                             item.getValue().writeTo(item.getKey(), output);
>                         }
>                     }
>                 }
>                 else {
>                     entry.getValue().writeTo(entry.getKey(), output);
>                 }
>             }
>
> Any help would be really appreciated.
>
> Thanks,
>
> Joan.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/protobuf/d7cf1a43-2613-4dd1-8e80-2fbbd2b5db77n%40googlegroups.com.

Reply via email to