The main idea of this program is to read the data and extract File and folder name from the buffer. The payload data can look like this : cached_folder\test1_file. The function get_folder_file_name extracts the folder and file name since we don't know the length of data so it's reasonable to use realloc() function to expand buffer as per requirement since it's running on memory limited device (embedded).
Here is the code :
typedef struct command_packet
{
uint32_t trigger_mode;
uint32_t command_status;
uint8_t payload_data[];
}COMMAND_PACKET;
//This function is called in main whenever there is incoming packet from TCP which has payload, command status and mode.
int32_t Analyse_stream(COMMAND_PACKET *pcommand, int32_t payload_data_length)
{
char *file_name = (char *)malloc(sizeof(char));
char *folder_name = (char *)malloc(sizeof(char));
int file_name_len= 0;
int folder_len = 0;
uint16_t status;
if ((status = get_folder_file_name(pcommand->payload_data, payload_data_length, file_name,folder_name, &file_name_len, &folder_len )) != SUCCESS)
{
free(file_name);
free(folder_name);
return status;
}
printf("File Name = %s\n", file_name);
printf("Folder = %s\n", folder_name);
free(file_name);
file_name = NULL;
free(folder_name);
folder_name = NULL;
}
//This function is called in stored_byte_stream to extract the folder and file name.
int32_t get_folder_file_name(uint8_t *payload_data, int32_t payload_data_len, char *file_name, char *folder_name, int32_t *file_name_len, int32_t *folder_len )
{
int i = 0;
int k=0;
// Check until null character to get the file name
// For alignment with u16, single null char is added at the end of the file name for
// a file name with strlen as odd and two null chars for a file name with even strlen
do{
if(payload_data[i] == '/')
{
if(i > 0)
k = i+1;
}
i++;
}while((*(payload_data + i) != '\0') && (i < payload_data_len));
if(k == 0)
{
return FOLDER_NAME_IS_EMPTY;
}
if (i == payload_data_len)
{
// Null char search completed till the end of the payload len, No filename found
return FILE_NAME_NOT_FOUND;
}
if (i == 1)
{
// File Name strlen = 0; implies that the file name was not provided
return FILE_NAME_IS_EMPTY;
}
*folder_len = k+1;
*file_name_len= i-k+1;
folder_name = realloc(folder_name, sizeof(char) *(*folder_len));
strncpy(folder_name, (char *)payload_data, *folder_len -1);
file_name = realloc(file_name, sizeof(char) *(*file_name_len));
strncpy(file_name, (char *)payload_data + k, *file_name_len);
return SUCCESS;
}
So, the issue I am facing is whenever the size of file_name_len or folder_len exceeds by 13, it prints nothing. The function get_folder_file_name returns empty file name or folder name whichever exceeds by 13. But in this same function folder_name & file name also has correct data but when they return if any of them exceeds by 13 length, buffer is empty. The issue gets fixed if I allocate fixed memory in initialization like char *file_name = (char *)malloc(15); and char *folder_name = (char *)malloc(15); and then doing realloc() it gets fixed. What I am doing wrong?
malloc(sizeof(char))-- That's not much. (It's just one byte, just enough for the terminator on an empty string.)mallocorrealloc. I would say that you shouldn't cast anything by default, unless the compiler complains.sizeof(char)is specified to always be equal to1(so you don't have to multiply by that). Andstrncpymight not add a null-terminator in your string (and are you sure you allocate space for it).get_folder_file_namehandle the allocation, you should alter the function so that the calling function knows about the changes you've made to the pointer. As is, you just re-allocate to a local variable, which will be lost afterget_folder_file_namereturns. You could return the handle to the allocated memory:char *p = get_folder_file_name(...), for example.