Uploading an Object Body

By uploading a file as an object body, you can associate and manage the file with a KiiObject. For the overview of the object body, see Accessing an Object Body.

The Thing SDK Embedded offers the following two methods for uploading an object body:

For both methods, an object body in the KiiObject will be replaced with the new one when the upload is finished; the old one will be deleted automatically. If the object body is uploaded simultaneously, the last one uploaded will remain; there is no optimistic lock feature for the object body.

There is no limit to the size of an object body when you upload an object body in multiple pieces (you can store as much object bodies as you want until the total size reaches your plan's limit). If you upload an object body at once, the maximum size of an object body is limited to 100 MB. For the server stability, we kindly ask you to finish one upload request in about one minute.

Be careful with the buffer size specified at initialization if you increase the data size per transfer. The total size of transferred data per API call including command options such as HTTP headers must be less than or equal to the buffer size specified at initialization.

Uploading an object body in multiple pieces

The following sample code shows how to upload an object body.

/* Set object body parameters. */
#define OBJECT_ID "STATUS_TEMPERATURE"
#define CONTENT_TYPE "application/octet-stream"

char OBJECT_BODY1[] = {
  0x31, 0x32, 0x33, 0x00, 0x34, 0x35, 0x36, 0x00, 0x37, 0x38, 0x39, 0x00
};
char OBJECT_BODY2[] = {
  0x36, 0x35, 0x34, 0x00, 0x33, 0x32, 0x31, 0x00
};
char uploadID[KII_UPLOADID_SIZE + 1];
kii_chunk_data_t chunkData1, chunkData2;

/* Set bucket parameters. */
kii_bucket_t bucket;
memset(&bucket, 0x00, sizeof(kii_bucket_t));
bucket.scope = KII_SCOPE_THING;
bucket.bucket_name = "myBucket";
bucket.scope_id = "VENDOR_THING_ID:rBnvSPOXBDF9r29GJeGS";

/* Upload the object body in chunks. */
ret = kii_object_init_upload_body(&kii, &bucket, OBJECT_ID, uploadID);
if (ret != 0) {
  /* Handle the error. */
  return;
}

/* Set the first chunk. */
chunkData1.body_content_type = CONTENT_TYPE;
chunkData1.position = 0;
chunkData1.length = sizeof(OBJECT_BODY1) / sizeof(OBJECT_BODY1[0]);
chunkData1.total_length = sizeof(OBJECT_BODY1) / sizeof(OBJECT_BODY1[0]) + sizeof(OBJECT_BODY2) / sizeof(OBJECT_BODY2[0]);
chunkData1.chunk = OBJECT_BODY1;

/* Upload the first chunk. */
ret = kii_object_upload_body(&kii, &bucket, OBJECT_ID, uploadID, &chunkData1);
if (ret != 0) {
  /* Handle the error. */
  return;
}

/* Set the second chunk. */
chunkData2.body_content_type = CONTENT_TYPE;
chunkData2.position = chunkData1.length;
chunkData2.length = sizeof(OBJECT_BODY2) / sizeof(OBJECT_BODY2[0]);
chunkData2.total_length = chunkData1.total_length;
chunkData2.chunk = OBJECT_BODY2;

/* Upload the second chunk. */
ret = kii_object_upload_body(&kii, &bucket, OBJECT_ID, uploadID, &chunkData2);
if (ret != 0) {
  /* Handle the error. */
  return;
}

/* Finalize the upload. */
ret = kii_object_commit_upload(&kii, &bucket, OBJECT_ID, uploadID, 1);
if (ret != 0) {
  /* Handle the error. */
  return;
}

When you upload an object body in multiple pieces, the object body is split into chunks and then uploaded. In the above example, the object body is split into two chunks then uploaded.

The sample code consists of the following three types of API calls. Two of the four API calls uses the same API to upload the chunks.

  • kii_object_init_upload_body

    This API starts to upload an object body. To do so, you need to create a KiiObject on the server beforehand.

    Specify the KiiObject that will hold the object body with the kii_bucket_t structure and KiiObject ID. See Creating a KiiObject to learn how to specify the bucket.

    The last argument is a pointer to the space where the upload ID is stored. The subsequent API calls use the obtained upload ID for requests. Reserve a space of a minimum of KII_UPLOADID_SIZE + 1 bytes.

    Implement the rollback process with the kii_object_commit_upload if possible, in order to cancel the upload process after the upload ID is obtained due to an event such as an error (Such a process is omitted in this sample code).

  • kii_object_upload_body

    This API uploads data chunks of the object body and adds them to the data which have already been uploaded. Kii Cloud still accepts the next chunk after execution of this API and the object body has not been overwritten.

    The target KiiObject is identified with the kii_bucket_t structure, KiiObject ID, and upload ID.

    Specify the chunk to upload with the kii_chunk_data_t structure as below.

    Member Description
    body_content_type The Content-Type of the data in the form of "type/subtype". Use the same string for all the chunks. The Content-Type sent to Kii Cloud will be used when the object body is downloaded and when the object body is published and viewed on the browser.
    position The position to start uploading the object body. This is 0 for the first chunk and the total size of uploaded data for the subsequent chunks.
    length The data length of the chunk in bytes. It is the valid size of data to which the chunk points.
    total_length The total size of all the combined chunks
    chunk The pointer to the data included in the chunk

    You can call the kii_object_upload_body repeatedly until the entire data is uploaded.

  • kii_object_commit_upload

    This API commits or cancels the uploaded object body.

    The target KiiObject is identified with the kii_bucket_t structure, KiiObject ID, and upload ID.

    If the last argument is 1 or more, the upload will be committed and the object body will be overwritten with the new one. If the last argument is 0, the upload will be canceled and the object body remains unchanged.

This sample splits the object body whose size is 24 bytes into two chunks and uploads them for testing purposes. The first call of the kii_object_upload_body() registers 12 bytes in the OBJECT_BODY1 and the second call registers 8 bytes in the OBJECT_BODY2. Committing them registers one object body of 24 bytes.

You can register the object body even if the thing shuts down between the API calls as far as the upload ID and the chunk position are properly managed. This secures uploads of large object bodies against interruptions.

Uploading an object body at once

You can upload an entire object body with one API call without splitting data into chunks (We recommend uploading an object body in multiple pieces, especially when you are uploading a big file to Kii Cloud).

Check the following sample code to see how you can do this.

/* Set object body parameters. */
#define OBJECT_ID "STATUS_TEMPERATURE"
#define CONTENT_TYPE "application/octet-stream"
#define OBJECT_LENGTH 12

char OBJECT_BODY[] = {
  0x31, 0x32, 0x33, 0x00, 0x34, 0x35, 0x36, 0x00, 0x37, 0x38, 0x39, 0x00
};

/* Set bucket parameters. */
kii_bucket_t bucket;
memset(&bucket, 0x00, sizeof(kii_bucket_t));
bucket.scope = KII_SCOPE_THING;
bucket.bucket_name = "myBucket";
bucket.scope_id = "VENDOR_THING_ID:rBnvSPOXBDF9r29GJeGS";

/* Upload the object body. */
ret = kii_object_upload_body_at_once(&kii, &bucket, OBJECT_ID, CONTENT_TYPE, OBJECT_BODY, OBJECT_LENGTH);
if (ret != 0) {
  /* Handle the error. */
  return;
}

Use the kii_object_upload_body_at_once function to upload the content of the specified buffer as an object body. One API call uploads the entire object body and updates the object body on the server. You need to create a KiiObject on the server beforehand.

The target KiiObject is identified with the kii_bucket_t structure and KiiObject ID. See Creating a KiiObject to learn how to specify the bucket.

Set the Content-Type of the data in the form of "type/subtype". The Content-Type sent to Kii Cloud will be used when the object body is downloaded and when the object body is published and viewed on the browser.