Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- #include "assert.h"
- #include "message.h"
- typedef enum {
- Clockwise, Anti_Clockwise
- } Rotation;
- static char *copyString(const char* inputString);
- static MessageResult messageRotate(Message message, Rotation direction);
- #define COLOR_MAX 255
- // Defines for returning frequently used errors;
- #define IF_NULL_RETURN_NULL(var) { \
- if ( ((var) == NULL)) return NULL; }
- #define IF_NULL_RETURN_NULL_ARGUMENT(var) { \
- if ( ((var) == NULL)) return MESSAGE_NULL_ARGUMENT; }
- #define IS_WRONG_TYPE(message,messageType) { \
- if ( ((message->type) != messageType)) return MESSAGE_WRONG_TYPE; }
- //
- // int main(void) {
- // setvbuf(stdout, NULL, _IONBF, 0);
- // Fix no output in debug mode bug
- // setvbuf(stderr, NULL, _IONBF, 0); // Fix no output in debug mode bug
- // Test copyString()
- // char *gal=NULL;
- // char gall[3]="gal";
- // printf("%s\n", gall);
- // gal=copyString(gall);
- // printf("%s\n", gal);
- // int senderID = 5;
- // const char *text="a\nb\nc";
- // Message new_message = messageTextCreate(senderID,text);
- // if (new_message == NULL) {
- // return 0;
- // }
- // printf("userid: %d text: %s\n", new_message->senderID, new_message->content.text);
- // int number=messageNumberOfLines(new_message);
- // printf("number_lines: %d", number);
- // int senderID = 1;
- // char *text1 = "\n";
- // Message newMessage1 = messageTextCreate(senderID, text1);
- // if (newMessage1 == NULL) {
- // return 0;
- // }
- // char *outValue=malloc(sizeof(*outValue));
- // messageGetCharacter(newMessage1,0,0,outValue);
- // printf("%c", *outValue);
- // printf("userid: %d text: %s\n", newMessage1->senderID,
- // newMessage1->content.text);
- // //int number1=messageNumberOfLines(new_message1);
- // //printf("number_lines: %d\n", number1);
- // char *text2 = "Fiass\n:|";
- // Message newMessage2 = messageTextCreate(senderID, text2);
- // if (newMessage2 == NULL) {
- // return 0;
- // }
- // printf("userid: %d text: %s\n", newMessage2->senderID,
- // newMessage2->content.text);
- // //Message messageImageCreate( int senderID, const unsigned char* const* image,
- // //unsigned width, unsigned height) {
- // unsigned char **picture=malloc(sizeof(*picture));
- // int height=3; int width=3;
- // for (int i=0; i<height; i++) {
- // picture[i]=malloc(sizeof(*picture[i]) * width);
- // }
- // for (int i=0; i < height; i++) {
- // for (int j=0; j < width; j++) {
- // picture[i][j] = (1 + width*i + j);
- // }
- // }
- // Message msg_img=messageImageCreate(senderID,(const unsigned char* const *)picture, width, height);
- // for (int i=0; i < msg_img->content.image.height; i++) {
- // for (int j=0; j < msg_img->content.image.width; j++) {
- // printf("%d", msg_img->content.image.data[i][j]);
- // }
- // printf("\n");
- // }
- // printf("\n");
- // messageRotateClockwise(msg_img);
- // for (int i=0; i < msg_img->content.image.height; i++) {
- // for (int j=0; j < msg_img->content.image.width; j++) {
- // printf("%d", msg_img->content.image.data[i][j]);
- // }
- // printf("\n");
- // }
- // printf("\n");
- // messageRotateClockwise(msg_img);
- // for (int i=0; i < msg_img->content.image.height; i++) {
- // for (int j=0; j < msg_img->content.image.width; j++) {
- // printf("%d", msg_img->content.image.data[i][j]);
- // }
- // printf("\n");
- // }
- //
- // printf("\n");
- // messageRotateAntiClockwise(msg_img);
- // for (int i=0; i < msg_img->content.image.height; i++) {
- // for (int j=0; j < msg_img->content.image.width; j++) {
- // printf("%d", msg_img->content.image.data[i][j]);
- // }
- // printf("\n");
- // }
- // printf("\n");
- // messageRotateAntiClockwise(msg_img);
- // for (int i=0; i < msg_img->content.image.height; i++) {
- // for (int j=0; j < msg_img->content.image.width; j++) {
- // printf("%d", msg_img->content.image.data[i][j]);
- // }
- // printf("\n");
- // }
- // Message s=messageCopy(msg_img);
- // for (int i=0; i < s->content.image.height; i++) {
- // for (int j=0; j < s->content.image.width; j++) {
- // printf("%d", s->content.image.data[i][j]);
- // }
- // printf("\n");
- // }
- // Message b=messageCopy(newMessage1);
- // messageConcat(newMessage1, b);
- // printf("\nconcat: ~~~%s~~~\n", newMessage1->content.text);
- // messageDestroy(b);
- // messageDestroy(s);
- // return 0;
- // }
- Message messageImageCreate( int senderID, const unsigned char* const* image,
- unsigned width, unsigned height) {
- IF_NULL_RETURN_NULL(image);
- if ( (width <= 0) || (height <= 0) ) {
- return NULL;
- }
- int i=0, j=0;
- Message new_image = malloc(sizeof(*new_image));
- if (!new_image)
- return NULL;
- if( !(new_image->content.image.data =
- malloc(sizeof(*new_image->content.image.data)*height)) )
- return NULL;
- for (i = 0; i < height; i++) {
- if ( !(new_image->content.image.data[i] =
- malloc(sizeof(*new_image->content.image.data[i])*width)) ) {
- for (; i > 0; i--)
- free (new_image->content.image.data[i-1]);
- free(new_image->content.image.data);
- free(new_image);
- return NULL;
- }
- }
- new_image->senderID = senderID;
- new_image->type = MESSAGE_IMAGE;
- new_image->content.image.height = height;
- new_image->content.image.width = width;
- for ( i=0; i < height; i++)
- for ( j=0; j < width; j++)
- new_image->content.image.data[i][j] = image[i][j];
- return new_image;
- }
- /* messageTextCreate(int,const char*)
- Gets a number representing the senderID and a string representing the text
- message. Returns a new message object, or NULL if allocation failed */
- Message messageTextCreate(int senderID, const char* text) {
- IF_NULL_RETURN_NULL(text)
- Message newMessage = malloc(sizeof(*newMessage));
- IF_NULL_RETURN_NULL(newMessage)
- newMessage->senderID = senderID;
- newMessage->content.text = copyString(text);
- if (newMessage->content.text == NULL) {
- free(newMessage);
- return NULL;
- }
- newMessage->type = MESSAGE_TEXT;
- return newMessage;
- }
- /* copyString(const char*)
- Gets a string, copy it to new allocated space.
- Returns a pointer to the new string, or returns NULL if allocation failed */
- static char *copyString(const char* inputString) {
- assert(inputString != NULL);
- char *newString = malloc(sizeof(*newString)*(strlen(inputString) + 1));
- IF_NULL_RETURN_NULL(newString)
- strcpy(newString, inputString);
- return newString;
- }
- MessageResult messageIsPalindrome(const Message message, bool* outIsPalindrome) {
- if ( !message )
- return MESSAGE_NULL_ARGUMENT;
- if ( !message->content.text )
- return MESSAGE_NULL_ARGUMENT;
- if ( (message->type) == MESSAGE_IMAGE)
- return MESSAGE_WRONG_TYPE;
- int i;
- char* str = copyString(message->content.text);
- if (str == NULL) {
- return MESSAGE_OUT_OF_MEMORY;
- }
- int j, startNewLine=0;
- (*outIsPalindrome) = true;
- for ( i = 0; i < (strlen(str)+1) ; i++ ) {
- if (str[i] == '\0' || str[i] == '\n') {
- int lastCharInLine=0;
- for ( j = startNewLine; j < i-1-lastCharInLine; j++) {
- if (str[j] != str[i-1-lastCharInLine++]) {
- (*outIsPalindrome) = false;
- break;
- }
- }
- if (*outIsPalindrome == false)
- break;
- startNewLine = i+1;
- }
- }
- free(str);
- return MESSAGE_SUCCESS;
- }
- /* messageNumerOfLines(const Message)
- Gets a message object.
- Returns number of lines in the message's text. */
- int messageNumberOfLines(const Message message) {
- if ((message == NULL) || (message->content.text == NULL)
- || (message->type == MESSAGE_IMAGE)) {
- return -1;
- }
- int linesCounter = 1;
- char *text = message->content.text;
- while (*text != '\0') {
- if (*text++ == '\n') {
- linesCounter++;
- }
- }
- return linesCounter;
- }
- /* messageConcat(Message,Message)
- Gets two message objects.
- Concatenate the first message's text to the second message's text.
- Returns success\error according to specification. */
- MessageResult messageConcat(Message message1, const Message message2) {
- IF_NULL_RETURN_NULL_ARGUMENT(message1)
- IF_NULL_RETURN_NULL_ARGUMENT(message1->content.text)
- IF_NULL_RETURN_NULL_ARGUMENT(message2)
- IF_NULL_RETURN_NULL_ARGUMENT(message2->content.text)
- IS_WRONG_TYPE(message1,MESSAGE_TEXT)
- IS_WRONG_TYPE(message2,MESSAGE_TEXT)
- if (message1->senderID != message2->senderID) {
- return MESSAGE_DIFFERENT_SENDER; // Messages sent from different users
- }
- char *concatenatedMessage = NULL;
- int concatMessageLen = messageLength(message1)+messageLength(message2)+2;
- concatenatedMessage = malloc(
- sizeof(*concatenatedMessage) * concatMessageLen);
- if (concatenatedMessage == NULL) {
- return MESSAGE_OUT_OF_MEMORY; // Memory allocation failed
- }
- *concatenatedMessage = '\0';
- concatenatedMessage = strcat(
- strcat(strcat(concatenatedMessage, message1->content.text), "\n"),
- message2->content.text);
- free(message1->content.text);
- message1->content.text = concatenatedMessage;
- return MESSAGE_SUCCESS; // Concatenation completed successfully
- }
- int messageLength(const Message message) {
- if (!message)
- return -1;
- if (!message->content.text)
- return -1;
- return (strlen(message->content.text));
- }
- MessageResult messageGetCharacter(const Message message, int line, int index,
- char* outValue) {
- if ( !message )
- return MESSAGE_NULL_ARGUMENT;
- if ( (message->type) == MESSAGE_IMAGE)
- return MESSAGE_WRONG_TYPE;
- char* str = copyString(message->content.text);
- if (str == NULL)
- return MESSAGE_OUT_OF_MEMORY;
- if (str[0] == 0) {
- free(str);
- return MESSAGE_OUT_OF_BOUNDS;
- }
- int lineCounter = 0, inRightPlace = 0, chIndex = 0;
- for ( int i = 0; i < (strlen(str)+1); i++ ) {
- if (str[i] == '\n') { // Search for the right line
- lineCounter++;
- chIndex++;
- }
- else chIndex++;
- if (lineCounter == line) {
- inRightPlace++;
- int j = 0;
- while ( j != index ) { // Search for the right index
- if ( j > index) {
- free(str);
- return MESSAGE_OUT_OF_BOUNDS;
- }
- j++;
- chIndex++;
- }
- if (str[chIndex] == 0) {
- free(str);
- return MESSAGE_OUT_OF_BOUNDS;
- }
- (*outValue) = str[chIndex];
- inRightPlace++;
- break;
- }
- else if(lineCounter > line) {
- free(str);
- return MESSAGE_OUT_OF_BOUNDS;
- }
- }
- if (inRightPlace != 2) {
- free(str);
- return MESSAGE_OUT_OF_BOUNDS;
- }
- free(str);
- return MESSAGE_SUCCESS;
- }
- /* messageInvertColors(Message)
- Gets a message object.
- Inverts the colors of picture's message
- Returns success\error according to specification. */
- MessageResult messageInvertColors(Message message) {
- IF_NULL_RETURN_NULL_ARGUMENT(message)
- IF_NULL_RETURN_NULL_ARGUMENT(message->content.image.data)
- IS_WRONG_TYPE(message,MESSAGE_IMAGE)
- for (int i=0; i < message->content.image.height; i++) {
- for (int j=0; j< message->content.image.width; j++) {
- message->content.image.data[i][j]=255-message->content.image.data[i][j];
- }
- }
- return MESSAGE_SUCCESS;
- }
- /* messageRotate(Message,Rotation)
- Gets a message object.
- Rotates the message's image by 90 degrees clockwise or anti-clockwise.
- Returns success\error according to specification. */
- static MessageResult messageRotate(Message message, Rotation direction) {
- IF_NULL_RETURN_NULL_ARGUMENT(message)
- IF_NULL_RETURN_NULL_ARGUMENT(message->content.image.data)
- IS_WRONG_TYPE(message,MESSAGE_IMAGE)
- // imagePre[heightPre][widthPre]
- unsigned char **imagePre = message->content.image.data; // image before rotation
- int heightPre = message->content.image.height; // image height before rotation
- int widthPre = message->content.image.width; // image width before rotation
- // imagePost[widthPost][heightPost]
- int heightPost = widthPre; // image height after rotation
- int widthPost = heightPre; // image width after rotation
- unsigned char **imagePost = malloc(sizeof(*imagePost)*heightPost);
- if (imagePost == NULL) {
- return MESSAGE_OUT_OF_MEMORY;
- }
- for (int i=0; i < heightPost; i++) {
- imagePost[i] = malloc(sizeof(**imagePost)*widthPost);
- if (imagePost[i] == NULL) {
- for (int j=0; j<i; j++) {
- free (imagePost[j]);
- free (imagePost);
- }
- return MESSAGE_OUT_OF_MEMORY;
- }
- }
- for (int i = 0; i < heightPost; i++) {
- for (int j = 0; j < widthPost; j++) {
- imagePost[i][j] = ( (direction == Clockwise) ? imagePre[heightPre-1-j][i] : imagePre[j][widthPre-1-i] );
- }
- }
- message->content.image.data = imagePost;
- message->content.image.height = heightPost;
- message->content.image.width = widthPost;
- for (int i=0;i<heightPre;i++) { // Freeing ImagePre's every string
- free(imagePre[i]);
- }
- free(imagePre); // Freeing the array of strings
- return MESSAGE_SUCCESS;
- }
- /* messageRotateClockwise(Message)
- Gets a message object.
- Rotates the message's image by 90 degrees clock-wise using messageRotate().
- Returns success\error according to specification. */
- MessageResult messageRotateClockwise(Message message) {
- return messageRotate(message,Clockwise);
- }
- /* messageRotateAntiClockwise(Message)
- Gets a message object.
- Rotates the message's image by 90 degrees counter clock-wise using messageRotate().
- Returns success\error according to specification. */
- MessageResult messageRotateAntiClockwise(Message message) {
- return messageRotate(message,Anti_Clockwise);
- }
- MessageResult messageGetColor(const Message message, unsigned row, unsigned
- column, unsigned char* outColor) {
- if ( !message )
- return MESSAGE_NULL_ARGUMENT;
- if (message->type == MESSAGE_TEXT)
- return MESSAGE_WRONG_TYPE;
- if (message->content.image.height < row + 1
- || message->content.image.width < column + 1)
- return MESSAGE_OUT_OF_BOUNDS;
- if(!message->content.image.data[row][column])
- return MESSAGE_OUT_OF_BOUNDS;
- (*outColor) = message->content.image.data[row][column];
- return MESSAGE_SUCCESS;
- }
- MessageResult messageCompare(const Message message1, const Message message2,
- bool* outIdentical) {
- if ( !message1 || !message2)
- return MESSAGE_NULL_ARGUMENT;
- if (message1->type == message2->type &&
- message1->senderID == message2->senderID) {
- if (message1->type == MESSAGE_IMAGE) {
- for (int i = 0; i < message1->content.image.height; i++) {
- for (int j = 0; j < message1->content.image.width; j++) {
- if (message1->content.image.data[i][j] ==
- message2->content.image.data[i][j]) {
- (*outIdentical = true);
- }
- else (*outIdentical = false);
- }
- }
- }
- else {
- int len1 = messageLength(message1);
- int len2 = messageLength(message2);
- if (len1 != len2) {
- (*outIdentical) = false;
- }
- else {
- int counterIdentical = 0;
- for (int i = 0; i < len1; i++) {
- if (message1->content.text[i] == message2->content.text[i])
- counterIdentical++;
- }
- if (counterIdentical == len1)
- (*outIdentical) = true;
- }
- }
- }
- else (*outIdentical = false);
- return MESSAGE_SUCCESS;
- }
- /* messageCopy(const Message)
- Gets a message object.
- Returns a copy of the message. */
- Message messageCopy(const Message message) {
- IF_NULL_RETURN_NULL(message)
- Message messageCopy = malloc(sizeof(*messageCopy));
- IF_NULL_RETURN_NULL(messageCopy)
- messageCopy->senderID=message->senderID;
- messageCopy->type=message->type;
- switch (messageCopy->type) {
- case MESSAGE_TEXT :
- if (message->content.text == NULL) {
- free(messageCopy);
- return NULL;
- }
- char *textCopy = malloc(sizeof(*textCopy) * (strlen(message->content.text)+1));
- if (textCopy == NULL) {
- free(messageCopy);
- return NULL;
- }
- strcpy(textCopy,message->content.text);
- messageCopy->content.text=textCopy;
- break;
- case MESSAGE_IMAGE :
- if (message->content.image.data == NULL) {
- free(messageCopy);
- return NULL;
- }
- unsigned char **dataCopy = malloc(sizeof(*dataCopy) * message->content.image.height);
- if (dataCopy == NULL) {
- free(messageCopy);
- return NULL;
- }
- for (int i = 0; i < message->content.image.height; i++) {
- dataCopy[i]=malloc(sizeof(**dataCopy)*message->content.image.width);
- if (dataCopy[i] == NULL) {
- for (int j=0; j<i; j++) {
- free(dataCopy[j]);
- }
- free(dataCopy);
- free(messageCopy);
- return NULL;
- }
- for (int j = 0; j < message->content.image.width; j++) {
- dataCopy[i][j]=message->content.image.data[i][j];
- }
- }
- messageCopy->content.image.data=dataCopy;
- messageCopy->content.image.width=message->content.image.width;
- messageCopy->content.image.height=message->content.image.height;
- }
- return messageCopy;
- }
- /* messageDestroy(Message)
- Gets a message object and deletes it. */
- void messageDestroy(Message message) {
- switch (message->type) {
- case MESSAGE_TEXT:
- free(message->content.text);
- free(message);
- break;
- case MESSAGE_IMAGE:
- for (int i=0; i < message->content.image.height; i++) {
- free(message->content.image.data[i]);
- }
- free(message->content.image.data);
- free(message);
- break;
- }
- }
- MessageResult messageGetSenderID(const Message message, int* outSenderID) {
- if ( !message )
- return MESSAGE_NULL_ARGUMENT;
- (*outSenderID) = message->senderID;
- return MESSAGE_SUCCESS;
- }
- MessageResult messageGetType(const Message message, MessageType* outType) {
- if ( !message )
- return MESSAGE_NULL_ARGUMENT;
- if (message->type == MESSAGE_IMAGE)
- (*outType) = MESSAGE_IMAGE;
- else (*outType) = MESSAGE_TEXT;
- return MESSAGE_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement