Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cbor_encode_cbor #162

Open
mkm85 opened this issue Jul 19, 2019 · 9 comments
Open

Add cbor_encode_cbor #162

mkm85 opened this issue Jul 19, 2019 · 9 comments

Comments

@mkm85
Copy link
Contributor

mkm85 commented Jul 19, 2019

I propose adding a function which can encode encoded cbor into a CborEncoder.

Lets assume you have a system where chunks of data is encoded as cbor. If you are going to merge these chunks into a new cbor map they have to be decoded and then encoded again into the map. If instead one can just make a map and insert the binary cbor directly into this map then a decoding and reencoding is unneccessary.

CborError cbor_encode_cbor(CborEncoder* encoder, uint8_t* cbor, size_t size);

Regards, Michael

@thiagomacieira
Copy link
Member

The problem will be that we still need to decode and re-encode in order to keep the state in CborEncoder: it tries to keep the count of elements added, so it can tell you if you made a mistake.

Copying without decoding would be only possible if the array or map has unknown length. Would that be acceptable?

@mkm85
Copy link
Contributor Author

mkm85 commented Jul 19, 2019

I was thinking about adding the cbor as a single value e.g.

uint8_t example1[5] = { 0x82, 0x01, 0x82, 0x02, 0x03 };
uint8_t example2[8] = { 0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 60x1, 0x63 };

CborEncoder encoder;
cbor_encoder_init(&encoder, ....)
CborEncoder map;
cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
cbor_encode_text_stringz(&map, "foo");
cbor_encode_cbor(&map, example1, 5);
cbor_encode_text_stringz(&map, "bar");
cbor_encode_cbor(&map, example2, 8);
cbor_encoder_close_container(...)
...

I see that it will give some problems if the encoded cbor is containing multiple values.
And it would indeed be dangerous if an odd number of elements is added to a map. Maybe I is too dangerous to add such a functionality to the api.

@thiagomacieira
Copy link
Member

That we could easily do, yes.

@georgen117
Copy link

georgen117 commented Jul 19, 2019

There is a tag for a Cbor byte string.
(from RFC 7049)
2.4.4.1. Encoded CBOR Data Item

Sometimes it is beneficial to carry an embedded CBOR data item that
is not meant to be decoded immediately at the time the enclosing data
item is being parsed. Tag 24 (CBOR data item) can be used to tag the
embedded byte string as a data item encoded in CBOR format.

If we do use cbor encode cbor that tag should be used.

@mkm85
Copy link
Contributor Author

mkm85 commented Jul 19, 2019

Using a tag and a byte string is possible with the current api, but it was not the intended semantics with this request. So the name is probably not the best.

@thiagomacieira
Copy link
Member

Right, something like cbor_encode_encoded_item.

@sijohans
Copy link

I'll like to vote for this feature. I have two use cases where i have a hard coded cbor map or array that i would like to put into a high level map. E.g., i have a framework that receives a request to query for capabilities. An application on top of this layers defines the capabilities array.

/*
 * capabilities = {"modes": ["fly", "walk", "run"], "other": { ... }}
 * User defined function for getting capabilities.
 */
void get_capabilities(const uint8_t **ptr, size_t *size)
{
    /* Could be hard coded or created at startup for instance. */
    static uint8_t capabilities[] = { ... };
}


/* On a framework level. */
write_capabilities_response(CborEncoder *response)
{
   /* Here some other information are written to response that the framework requires. */
   .....

    /* Write user specified capabilities. */
    const uint8_t *capabilities = NULL;
    size_t size = 0;
    get_capabilities(&capabilities, &size);
    verify(capabilities != NULL and size > 0)
    cbor_encode_text_stringz(&response, "capabilities");
    cbor_encode_cbor(&response, capabilities, size);
}

I realize this was quite a bad example. But i have maps and arrays defined elsewhere and want to write them into the encoder.

TSonono pushed a commit to TSonono/tinycbor that referenced this issue Nov 20, 2019
This method allows for writing raw data directly to the encoding buffer. This can be useful if you have something stored as CBOR encoded data.

Fixes intel#162.

Signed-off-by: Tofik Sonono <tofiksonono@msn.com>
@ayechanpyaesonework
Copy link

ayechanpyaesonework commented Mar 26, 2020

Hello. I tried to use TSonono solution and it gave me an error. What I am trying to do is. I want to add cbor tagged data into array. Please see my below code. It gave me an error when i try to close the container.

else if ([object isKindOfClass:NSData.class]) {
        NSData *dataObject = (NSData *)object;
     
        CborParser parser;
        CborValue value;
        const int flags = 0;
        
        uint8_t *inBuffer = (uint8_t *)dataObject.bytes;
        size_t inBufferLen = dataObject.length;
        
        CborError err = cbor_parser_init(inBuffer, inBufferLen, 0, &parser, &value);
        CborType i = cbor_value_get_type(&value);
        
        
        if(i == CborTagType) {
            return [self ds_performSafeEncodingIntoBuffer:buffer bufferSize:bufferSize encoder:encoder encodingBlock:^CborError {
                return cbor_encode_raw(encoder,  inBuffer, inBufferLen);
            }];
        }

    }

This is the code for cbor_encode_raw
CborError cbor_encode_raw(CborEncoder *encoder, const uint8_t *raw, size_t length) { return append_to_buffer(encoder, raw, length); }

@thiagomacieira
Copy link
Member

thiagomacieira commented Apr 6, 2020

Your code is not correct, unless you're certain that the buffer you got contains exactly one item. What error did you get?

sjlongland pushed a commit to widesky/tinycbor that referenced this issue Jun 21, 2024
This method allows for writing raw data directly to the encoding buffer. This can be useful if you have something stored as CBOR encoded data.

Fixes intel#162.

Signed-off-by: Tofik Sonono <tofiksonono@msn.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants