Advertisement
Guest User

message.c

a guest
Nov 26th, 2014
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.59 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5.  
  6. #include "assert.h"
  7. #include "message.h"
  8.  
  9. typedef enum {
  10.         Clockwise, Anti_Clockwise
  11. } Rotation;
  12.  
  13. static char *copyString(const char* inputString);
  14. static MessageResult messageRotate(Message message, Rotation direction);
  15.  
  16. #define COLOR_MAX 255
  17.  
  18. // Defines for returning frequently used errors;
  19. #define IF_NULL_RETURN_NULL(var) { \
  20.                 if ( ((var) == NULL)) return NULL; }
  21. #define IF_NULL_RETURN_NULL_ARGUMENT(var) { \
  22.                 if ( ((var) == NULL)) return MESSAGE_NULL_ARGUMENT; }
  23. #define IS_WRONG_TYPE(message,messageType) { \
  24.                 if ( ((message->type) != messageType)) return MESSAGE_WRONG_TYPE; }
  25. //
  26. //      int main(void) {
  27. //      setvbuf(stdout, NULL, _IONBF, 0);
  28. // Fix no output in debug mode bug
  29. //      setvbuf(stderr, NULL, _IONBF, 0); // Fix no output in debug mode bug
  30. //      Test copyString()
  31. //      char *gal=NULL;
  32. //      char gall[3]="gal";
  33. //      printf("%s\n", gall);
  34. //      gal=copyString(gall);
  35. //      printf("%s\n", gal);
  36. //      int senderID = 5;
  37. //      const char *text="a\nb\nc";
  38. //      Message new_message = messageTextCreate(senderID,text);
  39. //      if (new_message == NULL) {
  40. //              return 0;
  41. //      }
  42. //      printf("userid: %d text: %s\n", new_message->senderID, new_message->content.text);
  43. //      int number=messageNumberOfLines(new_message);
  44. //      printf("number_lines: %d", number);
  45. //              int senderID = 1;
  46. //              char *text1 = "\n";
  47. //              Message newMessage1 = messageTextCreate(senderID, text1);
  48. //              if (newMessage1 == NULL) {
  49. //                      return 0;
  50. //              }
  51. //              char *outValue=malloc(sizeof(*outValue));
  52. //              messageGetCharacter(newMessage1,0,0,outValue);
  53. //              printf("%c", *outValue);
  54. //              printf("userid: %d text: %s\n", newMessage1->senderID,
  55. //                              newMessage1->content.text);
  56. //              //int number1=messageNumberOfLines(new_message1);
  57. //              //printf("number_lines: %d\n", number1);
  58. //              char *text2 = "Fiass\n:|";
  59. //              Message newMessage2 = messageTextCreate(senderID, text2);
  60. //              if (newMessage2 == NULL) {
  61. //                      return 0;
  62. //              }
  63. //              printf("userid: %d text: %s\n", newMessage2->senderID,
  64. //                              newMessage2->content.text);
  65. //              //Message messageImageCreate( int senderID, const unsigned char* const* image,
  66. //              //unsigned width, unsigned height) {
  67. //              unsigned char **picture=malloc(sizeof(*picture));
  68. //              int height=3; int width=3;
  69. //              for (int i=0; i<height; i++) {
  70. //                      picture[i]=malloc(sizeof(*picture[i]) * width);
  71. //              }
  72. //              for (int i=0; i < height; i++) {
  73. //                      for (int j=0; j < width; j++) {
  74. //                              picture[i][j] = (1 + width*i + j);
  75. //                      }
  76. //              }
  77. //              Message msg_img=messageImageCreate(senderID,(const unsigned char* const *)picture, width, height);
  78. //              for (int i=0; i < msg_img->content.image.height; i++) {
  79. //                      for (int j=0; j < msg_img->content.image.width; j++) {
  80. //                              printf("%d", msg_img->content.image.data[i][j]);
  81. //                      }
  82. //                      printf("\n");
  83. //              }
  84. //              printf("\n");
  85. //              messageRotateClockwise(msg_img);
  86. //              for (int i=0; i < msg_img->content.image.height; i++) {
  87. //                      for (int j=0; j < msg_img->content.image.width; j++) {
  88. //                              printf("%d", msg_img->content.image.data[i][j]);
  89. //                      }
  90. //                      printf("\n");
  91. //              }
  92. //              printf("\n");
  93. //              messageRotateClockwise(msg_img);
  94. //              for (int i=0; i < msg_img->content.image.height; i++) {
  95. //                      for (int j=0; j < msg_img->content.image.width; j++) {
  96. //                              printf("%d", msg_img->content.image.data[i][j]);
  97. //                      }
  98. //                      printf("\n");
  99. //              }
  100. //
  101. //              printf("\n");
  102. //              messageRotateAntiClockwise(msg_img);
  103. //              for (int i=0; i < msg_img->content.image.height; i++) {
  104. //                      for (int j=0; j < msg_img->content.image.width; j++) {
  105. //                              printf("%d", msg_img->content.image.data[i][j]);
  106. //                      }
  107. //                      printf("\n");
  108. //              }
  109. //              printf("\n");
  110. //              messageRotateAntiClockwise(msg_img);
  111. //              for (int i=0; i < msg_img->content.image.height; i++) {
  112. //                      for (int j=0; j < msg_img->content.image.width; j++) {
  113. //                              printf("%d", msg_img->content.image.data[i][j]);
  114. //                      }
  115. //                      printf("\n");
  116. //              }
  117. //              Message s=messageCopy(msg_img);
  118. //              for (int i=0; i < s->content.image.height; i++) {
  119. //                      for (int j=0; j < s->content.image.width; j++) {
  120. //                              printf("%d", s->content.image.data[i][j]);
  121. //                      }
  122. //                      printf("\n");
  123. //              }
  124. //              Message b=messageCopy(newMessage1);
  125. //              messageConcat(newMessage1, b);
  126. //              printf("\nconcat: ~~~%s~~~\n", newMessage1->content.text);
  127. //              messageDestroy(b);
  128. //              messageDestroy(s);
  129. //              return 0;
  130. //      }
  131.  
  132. Message messageImageCreate( int senderID, const unsigned char* const* image,
  133. unsigned width, unsigned height) {
  134.         IF_NULL_RETURN_NULL(image);
  135.         if ( (width <= 0) || (height <= 0) ) {
  136.                 return NULL;
  137.         }
  138.         int i=0, j=0;
  139.         Message new_image = malloc(sizeof(*new_image));
  140.         if (!new_image)
  141.                 return NULL;
  142.         if( !(new_image->content.image.data =
  143.                         malloc(sizeof(*new_image->content.image.data)*height)) )
  144.                 return NULL;
  145.         for (i = 0; i < height; i++) {
  146.                 if ( !(new_image->content.image.data[i] =
  147.                                 malloc(sizeof(*new_image->content.image.data[i])*width)) ) {
  148.                         for (; i > 0; i--)
  149.                                 free (new_image->content.image.data[i-1]);
  150.                         free(new_image->content.image.data);
  151.                         free(new_image);
  152.                         return NULL;
  153.                 }
  154.         }
  155.         new_image->senderID = senderID;
  156.                 new_image->type = MESSAGE_IMAGE;
  157.                 new_image->content.image.height = height;
  158.                 new_image->content.image.width = width;
  159.         for ( i=0; i < height; i++)
  160.                 for ( j=0; j < width; j++)
  161.                         new_image->content.image.data[i][j] = image[i][j];
  162.         return new_image;
  163. }
  164.  
  165. /*      messageTextCreate(int,const char*)
  166.  Gets a number representing the senderID and a string representing the text
  167.  message. Returns a new message object, or NULL if allocation failed */
  168. Message messageTextCreate(int senderID, const char* text) {
  169.         IF_NULL_RETURN_NULL(text)
  170.         Message newMessage = malloc(sizeof(*newMessage));
  171.         IF_NULL_RETURN_NULL(newMessage)
  172.         newMessage->senderID = senderID;
  173.         newMessage->content.text = copyString(text);
  174.         if (newMessage->content.text == NULL) {
  175.                 free(newMessage);
  176.                 return NULL;
  177.         }
  178.         newMessage->type = MESSAGE_TEXT;
  179.         return newMessage;
  180. }
  181.  
  182. /*      copyString(const char*)
  183.  Gets a string, copy it to new allocated space.
  184.  Returns a pointer to the new string, or returns NULL if allocation failed */
  185. static char *copyString(const char* inputString) {
  186.         assert(inputString != NULL);
  187.         char *newString = malloc(sizeof(*newString)*(strlen(inputString) + 1));
  188.         IF_NULL_RETURN_NULL(newString)
  189.         strcpy(newString, inputString);
  190.         return newString;
  191. }
  192.  
  193. MessageResult messageIsPalindrome(const Message message, bool* outIsPalindrome) {
  194.         if ( !message )
  195.                 return MESSAGE_NULL_ARGUMENT;
  196.         if ( !message->content.text )
  197.                 return MESSAGE_NULL_ARGUMENT;
  198.         if ( (message->type) == MESSAGE_IMAGE)
  199.                 return MESSAGE_WRONG_TYPE;
  200.         int i;
  201.         char* str = copyString(message->content.text);
  202.         if (str == NULL) {
  203.                 return MESSAGE_OUT_OF_MEMORY;
  204.         }
  205.         int j, startNewLine=0;
  206.         (*outIsPalindrome) = true;
  207.         for ( i = 0; i < (strlen(str)+1) ; i++ ) {
  208.             if (str[i] == '\0' || str[i] == '\n') {
  209.                 int lastCharInLine=0;
  210.                 for ( j = startNewLine; j < i-1-lastCharInLine; j++) {
  211.                     if (str[j] != str[i-1-lastCharInLine++]) {
  212.                         (*outIsPalindrome) = false;
  213.                         break;
  214.                     }
  215.                 }
  216.                 if (*outIsPalindrome == false)
  217.                     break;
  218.                 startNewLine = i+1;
  219.             }
  220.         }
  221.     free(str);
  222.     return MESSAGE_SUCCESS;
  223. }
  224.  
  225. /*      messageNumerOfLines(const Message)
  226.  Gets a message object.
  227.  Returns number of lines in the message's text. */
  228. int messageNumberOfLines(const Message message) {
  229.         if ((message == NULL) || (message->content.text == NULL)
  230.                         || (message->type == MESSAGE_IMAGE)) {
  231.                 return -1;
  232.         }
  233.         int linesCounter = 1;
  234.         char *text = message->content.text;
  235.         while (*text != '\0') {
  236.                 if (*text++ == '\n') {
  237.                         linesCounter++;
  238.                 }
  239.         }
  240.         return linesCounter;
  241. }
  242.  
  243. /*      messageConcat(Message,Message)
  244.  Gets two message objects.
  245.  Concatenate the first message's text to the second message's text.
  246.  Returns success\error according to specification. */
  247. MessageResult messageConcat(Message message1, const Message message2) {
  248.         IF_NULL_RETURN_NULL_ARGUMENT(message1)
  249.         IF_NULL_RETURN_NULL_ARGUMENT(message1->content.text)
  250.         IF_NULL_RETURN_NULL_ARGUMENT(message2)
  251.         IF_NULL_RETURN_NULL_ARGUMENT(message2->content.text)
  252.         IS_WRONG_TYPE(message1,MESSAGE_TEXT)
  253.         IS_WRONG_TYPE(message2,MESSAGE_TEXT)
  254.         if (message1->senderID != message2->senderID) {
  255.                 return MESSAGE_DIFFERENT_SENDER; // Messages sent from different users
  256.         }
  257.         char *concatenatedMessage = NULL;
  258.         int concatMessageLen = messageLength(message1)+messageLength(message2)+2;
  259.         concatenatedMessage = malloc(
  260.                         sizeof(*concatenatedMessage) * concatMessageLen);
  261.         if (concatenatedMessage == NULL) {
  262.                 return MESSAGE_OUT_OF_MEMORY; // Memory allocation failed
  263.         }
  264.         *concatenatedMessage = '\0';
  265.         concatenatedMessage = strcat(
  266.                         strcat(strcat(concatenatedMessage, message1->content.text), "\n"),
  267.                         message2->content.text);
  268.         free(message1->content.text);
  269.         message1->content.text = concatenatedMessage;
  270.         return MESSAGE_SUCCESS; // Concatenation completed successfully
  271. }
  272.  
  273. int messageLength(const Message message) {
  274.         if (!message)
  275.                 return -1;
  276.         if (!message->content.text)
  277.                 return -1;
  278.         return (strlen(message->content.text));
  279. }
  280.  
  281.  
  282. MessageResult messageGetCharacter(const Message message, int line, int index,
  283.                                                             char* outValue) {
  284.         if ( !message )
  285.                 return MESSAGE_NULL_ARGUMENT;
  286.         if ( (message->type) == MESSAGE_IMAGE)
  287.                 return MESSAGE_WRONG_TYPE;
  288.         char* str = copyString(message->content.text);
  289.         if (str == NULL)
  290.                 return MESSAGE_OUT_OF_MEMORY;
  291.         if (str[0] == 0) {
  292.             free(str);
  293.             return MESSAGE_OUT_OF_BOUNDS;
  294.         }
  295.         int lineCounter = 0, inRightPlace = 0, chIndex = 0;
  296.         for ( int i = 0; i < (strlen(str)+1); i++ ) {
  297.             if (str[i] == '\n') {       // Search for the right line
  298.                 lineCounter++;
  299.                 chIndex++;
  300.             }
  301.             else chIndex++;
  302.             if (lineCounter == line) {
  303.                 inRightPlace++;
  304.                 int j = 0;
  305.                 while ( j != index ) {      // Search for the right index
  306.                     if ( j > index) {
  307.                         free(str);
  308.                         return MESSAGE_OUT_OF_BOUNDS;
  309.                     }
  310.                     j++;
  311.                     chIndex++;
  312.                 }
  313.                 if (str[chIndex] == 0) {
  314.                     free(str);
  315.                     return MESSAGE_OUT_OF_BOUNDS;
  316.                 }
  317.                 (*outValue) = str[chIndex];
  318.                 inRightPlace++;
  319.                 break;
  320.             }
  321.             else if(lineCounter > line) {
  322.                 free(str);
  323.                 return MESSAGE_OUT_OF_BOUNDS;
  324.             }
  325.         }
  326.         if (inRightPlace != 2) {
  327.             free(str);
  328.             return MESSAGE_OUT_OF_BOUNDS;
  329.         }
  330.         free(str);
  331.         return MESSAGE_SUCCESS;
  332. }
  333.  
  334. /*      messageInvertColors(Message)
  335.  Gets a message object.
  336.  Inverts the colors of picture's message
  337.  Returns success\error according to specification. */
  338. MessageResult messageInvertColors(Message message) {
  339.         IF_NULL_RETURN_NULL_ARGUMENT(message)
  340.         IF_NULL_RETURN_NULL_ARGUMENT(message->content.image.data)
  341.         IS_WRONG_TYPE(message,MESSAGE_IMAGE)
  342.         for (int i=0; i < message->content.image.height; i++) {
  343.                 for (int j=0; j< message->content.image.width; j++) {
  344.                         message->content.image.data[i][j]=255-message->content.image.data[i][j];
  345.                 }
  346.         }
  347.         return MESSAGE_SUCCESS;
  348. }
  349. /*      messageRotate(Message,Rotation)
  350.  Gets a message object.
  351.  Rotates the message's image by 90 degrees clockwise or anti-clockwise.
  352.  Returns success\error according to specification. */
  353. static MessageResult messageRotate(Message message, Rotation direction) {
  354.         IF_NULL_RETURN_NULL_ARGUMENT(message)
  355.         IF_NULL_RETURN_NULL_ARGUMENT(message->content.image.data)
  356.         IS_WRONG_TYPE(message,MESSAGE_IMAGE)
  357.         // imagePre[heightPre][widthPre]
  358.         unsigned char **imagePre = message->content.image.data; // image before rotation
  359.         int heightPre = message->content.image.height; // image height before rotation
  360.         int widthPre = message->content.image.width; // image width before rotation
  361.         // imagePost[widthPost][heightPost]
  362.         int heightPost = widthPre; // image height after rotation
  363.         int widthPost = heightPre; // image width after rotation
  364.         unsigned char **imagePost = malloc(sizeof(*imagePost)*heightPost);
  365.         if (imagePost == NULL) {
  366.                 return MESSAGE_OUT_OF_MEMORY;
  367.         }
  368.         for (int i=0; i < heightPost; i++) {
  369.                 imagePost[i] = malloc(sizeof(**imagePost)*widthPost);
  370.                 if (imagePost[i] == NULL) {
  371.                         for (int j=0; j<i; j++) {
  372.                                 free (imagePost[j]);
  373.                                 free (imagePost);
  374.                         }
  375.                         return MESSAGE_OUT_OF_MEMORY;
  376.                 }
  377.         }
  378.         for (int i = 0; i < heightPost; i++) {
  379.                  for (int j = 0; j < widthPost; j++) {
  380.                          imagePost[i][j] = ( (direction == Clockwise) ? imagePre[heightPre-1-j][i] : imagePre[j][widthPre-1-i] );
  381.                 }
  382.         }
  383.         message->content.image.data = imagePost;
  384.         message->content.image.height = heightPost;
  385.         message->content.image.width = widthPost;
  386.     for (int i=0;i<heightPre;i++) { // Freeing ImagePre's every string
  387.             free(imagePre[i]);
  388.     }
  389.         free(imagePre); // Freeing the array of strings
  390.         return MESSAGE_SUCCESS;
  391. }
  392.  
  393. /*      messageRotateClockwise(Message)
  394.  Gets a message object.
  395.  Rotates the message's image by 90 degrees clock-wise using messageRotate().
  396.  Returns success\error according to specification. */
  397. MessageResult messageRotateClockwise(Message message) {
  398.         return messageRotate(message,Clockwise);
  399. }
  400.  
  401. /*      messageRotateAntiClockwise(Message)
  402.  Gets a message object.
  403.  Rotates the message's image by 90 degrees counter clock-wise using messageRotate().
  404.  Returns success\error according to specification. */
  405. MessageResult messageRotateAntiClockwise(Message message) {
  406.         return messageRotate(message,Anti_Clockwise);
  407. }
  408.  
  409. MessageResult messageGetColor(const Message message, unsigned row, unsigned
  410.                 column, unsigned char* outColor) {
  411.         if ( !message )
  412.                 return MESSAGE_NULL_ARGUMENT;
  413.         if (message->type == MESSAGE_TEXT)
  414.         return MESSAGE_WRONG_TYPE;
  415.     if (message->content.image.height < row + 1
  416.             || message->content.image.width < column + 1)
  417.                 return MESSAGE_OUT_OF_BOUNDS;
  418.         if(!message->content.image.data[row][column])
  419.             return MESSAGE_OUT_OF_BOUNDS;
  420.         (*outColor) = message->content.image.data[row][column];
  421.         return MESSAGE_SUCCESS;
  422. }
  423.  
  424. MessageResult messageCompare(const Message message1, const Message message2,
  425.                 bool* outIdentical) {
  426.         if ( !message1 || !message2)
  427.                 return MESSAGE_NULL_ARGUMENT;
  428.         if (message1->type == message2->type &&
  429.                 message1->senderID == message2->senderID) {
  430.                 if (message1->type == MESSAGE_IMAGE) {
  431.                         for (int i = 0; i < message1->content.image.height; i++) {
  432.                                 for (int j = 0; j < message1->content.image.width; j++) {
  433.                                         if (message1->content.image.data[i][j] ==
  434.                                                 message2->content.image.data[i][j]) {
  435.                                                 (*outIdentical = true);
  436.                                         }
  437.                                         else (*outIdentical = false);
  438.                                 }
  439.                         }
  440.                 }
  441.                 else {
  442.                         int len1 = messageLength(message1);
  443.                         int len2 = messageLength(message2);
  444.                         if (len1 != len2) {
  445.                                 (*outIdentical) = false;
  446.                         }
  447.                         else {
  448.                                 int counterIdentical = 0;
  449.                                 for (int i = 0; i < len1; i++) {
  450.                                         if (message1->content.text[i] == message2->content.text[i])
  451.                                                 counterIdentical++;
  452.                                 }
  453.                                 if (counterIdentical == len1)
  454.                                         (*outIdentical) = true;
  455.                         }
  456.                 }
  457.         }
  458.         else (*outIdentical = false);
  459.         return MESSAGE_SUCCESS;
  460. }
  461.  
  462. /*      messageCopy(const Message)
  463.  Gets a message object.
  464.  Returns a copy of the message. */
  465. Message messageCopy(const Message message) {
  466.         IF_NULL_RETURN_NULL(message)
  467.         Message messageCopy = malloc(sizeof(*messageCopy));
  468.         IF_NULL_RETURN_NULL(messageCopy)
  469.         messageCopy->senderID=message->senderID;
  470.         messageCopy->type=message->type;
  471.         switch (messageCopy->type) {
  472.                 case MESSAGE_TEXT :
  473.                         if (message->content.text == NULL) {
  474.                                 free(messageCopy);
  475.                                 return NULL;
  476.                         }
  477.                         char *textCopy = malloc(sizeof(*textCopy) * (strlen(message->content.text)+1));
  478.                         if (textCopy == NULL) {
  479.                                 free(messageCopy);
  480.                                 return NULL;
  481.                         }
  482.                         strcpy(textCopy,message->content.text);
  483.                         messageCopy->content.text=textCopy;
  484.                         break;
  485.                 case MESSAGE_IMAGE :
  486.                         if (message->content.image.data == NULL) {
  487.                                 free(messageCopy);
  488.                                 return NULL;
  489.                         }
  490.                         unsigned char **dataCopy = malloc(sizeof(*dataCopy) * message->content.image.height);
  491.                         if (dataCopy == NULL) {
  492.                                 free(messageCopy);
  493.                                 return NULL;
  494.                         }
  495.                         for (int i = 0; i < message->content.image.height; i++) {
  496.                                 dataCopy[i]=malloc(sizeof(**dataCopy)*message->content.image.width);
  497.                                 if (dataCopy[i] == NULL) {
  498.                                         for (int j=0; j<i; j++) {
  499.                                                 free(dataCopy[j]);
  500.                                         }
  501.                                         free(dataCopy);
  502.                                         free(messageCopy);
  503.                                         return NULL;
  504.                                 }
  505.                                 for (int j = 0; j < message->content.image.width; j++) {
  506.                                         dataCopy[i][j]=message->content.image.data[i][j];
  507.                                 }
  508.                         }
  509.                         messageCopy->content.image.data=dataCopy;
  510.                         messageCopy->content.image.width=message->content.image.width;
  511.                         messageCopy->content.image.height=message->content.image.height;
  512.         }
  513.         return messageCopy;
  514. }
  515.  
  516. /*      messageDestroy(Message)
  517.  Gets a message object and deletes it. */
  518. void messageDestroy(Message message) {
  519.         switch (message->type) {
  520.                 case MESSAGE_TEXT:
  521.                         free(message->content.text);
  522.                         free(message);
  523.                         break;
  524.                 case MESSAGE_IMAGE:
  525.                         for (int i=0; i < message->content.image.height; i++) {
  526.                                 free(message->content.image.data[i]);
  527.                         }
  528.                         free(message->content.image.data);
  529.                         free(message);
  530.                         break;
  531.         }
  532. }
  533.  
  534. MessageResult messageGetSenderID(const Message message, int* outSenderID) {
  535.         if ( !message )
  536.                                 return MESSAGE_NULL_ARGUMENT;
  537.         (*outSenderID) = message->senderID;
  538.         return MESSAGE_SUCCESS;
  539. }
  540.  
  541. MessageResult messageGetType(const Message message, MessageType* outType) {
  542.         if ( !message )
  543.                 return MESSAGE_NULL_ARGUMENT;
  544.         if (message->type == MESSAGE_IMAGE)
  545.                 (*outType) = MESSAGE_IMAGE;
  546.         else (*outType) = MESSAGE_TEXT;
  547.         return MESSAGE_SUCCESS;
  548. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement