Advertisement
Guest User

Untitled

a guest
Nov 25th, 2014
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.39 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. //      if (newMessage1 == NULL) {
  48. //          return 0;
  49. //      }
  50. //      char *outValue=malloc(sizeof(*outValue));
  51. //      messageGetCharacter(newMessage1,0,0,outValue);
  52. //      printf("%c", *outValue);
  53. //      printf("userid: %d text: %s\n", newMessage1->senderID,
  54. //              newMessage1->content.text);
  55. //      //int number1=messageNumberOfLines(new_message1);
  56. //      //printf("number_lines: %d\n", number1);
  57. //      char *text2 = "Fiass\n:|";
  58. //      Message newMessage2 = messageTextCreate(senderID, text2);
  59. //      if (newMessage2 == NULL) {
  60. //          return 0;
  61. //      }
  62. //      printf("userid: %d text: %s\n", newMessage2->senderID,
  63. //              newMessage2->content.text);
  64. //      //Message messageImageCreate( int senderID, const unsigned char* const* image,
  65. //      //unsigned width, unsigned height) {
  66. //      unsigned char **picture=malloc(sizeof(*picture));
  67. //      int height=3; int width=3;
  68. //      for (int i=0; i<height; i++) {
  69. //          picture[i]=malloc(sizeof(*picture[i]) * width);
  70. //      }
  71. //      for (int i=0; i < height; i++) {
  72. //          for (int j=0; j < width; j++) {
  73. //              picture[i][j] = (1 + width*i + j);
  74. //          }
  75. //      }
  76. //      Message msg_img=messageImageCreate(senderID,(const unsigned char* const *)picture, width, height);
  77. //      for (int i=0; i < msg_img->content.image.height; i++) {
  78. //          for (int j=0; j < msg_img->content.image.width; j++) {
  79. //              printf("%d", msg_img->content.image.data[i][j]);
  80. //          }
  81. //          printf("\n");
  82. //      }
  83. //      printf("\n");
  84. //      messageRotateClockwise(msg_img);
  85. //      for (int i=0; i < msg_img->content.image.height; i++) {
  86. //          for (int j=0; j < msg_img->content.image.width; j++) {
  87. //              printf("%d", msg_img->content.image.data[i][j]);
  88. //          }
  89. //          printf("\n");
  90. //      }
  91. //      printf("\n");
  92. //      messageRotateClockwise(msg_img);
  93. //      for (int i=0; i < msg_img->content.image.height; i++) {
  94. //          for (int j=0; j < msg_img->content.image.width; j++) {
  95. //              printf("%d", msg_img->content.image.data[i][j]);
  96. //          }
  97. //          printf("\n");
  98. //      }
  99. //
  100. //      printf("\n");
  101. //      messageRotateAntiClockwise(msg_img);
  102. //      for (int i=0; i < msg_img->content.image.height; i++) {
  103. //          for (int j=0; j < msg_img->content.image.width; j++) {
  104. //              printf("%d", msg_img->content.image.data[i][j]);
  105. //          }
  106. //          printf("\n");
  107. //      }
  108. //      printf("\n");
  109. //      messageRotateAntiClockwise(msg_img);
  110. //      for (int i=0; i < msg_img->content.image.height; i++) {
  111. //          for (int j=0; j < msg_img->content.image.width; j++) {
  112. //              printf("%d", msg_img->content.image.data[i][j]);
  113. //          }
  114. //          printf("\n");
  115. //      }
  116. //      Message s=messageCopy(msg_img);
  117. //      for (int i=0; i < s->content.image.height; i++) {
  118. //          for (int j=0; j < s->content.image.width; j++) {
  119. //              printf("%d", s->content.image.data[i][j]);
  120. //          }
  121. //          printf("\n");
  122. //      }
  123. //      Message b=messageCopy(newMessage1);
  124. //      messageConcat(newMessage1, b);
  125. //      printf("\nconcat: ~~~%s~~~\n", newMessage1->content.text);
  126. //      messageDestroy(b);
  127. //      messageDestroy(s);
  128. //      return 0;
  129. //  }
  130.  
  131. Message messageImageCreate( int senderID, const unsigned char* const* image,
  132. unsigned width, unsigned height) {
  133.     IF_NULL_RETURN_NULL(image);
  134.     if ( (width <= 0) || (height <= 0) ) {
  135.         return NULL;
  136.     }
  137.     int i=0, j=0;
  138.     Message new_image = malloc(sizeof(*new_image));
  139.     if (!new_image)
  140.         return NULL;
  141.     if( !(new_image->content.image.data =
  142.             malloc(sizeof(*new_image->content.image.data)*height)) )
  143.         return NULL;
  144.     for (i = 0; i < height; i++) {
  145.         if ( !(new_image->content.image.data[i] =
  146.                 malloc(sizeof(*new_image->content.image.data[i])*width)) ) {
  147.             for (; i > 0; i--)
  148.                 free (new_image->content.image.data[i-1]);
  149.             free(new_image->content.image.data);
  150.             free(new_image);
  151.             return NULL;
  152.         }
  153.     }
  154.     new_image->senderID = senderID;
  155.         new_image->type = MESSAGE_IMAGE;
  156.         new_image->content.image.height = height;
  157.         new_image->content.image.width = width;
  158.     for ( i=0; i < height; i++)
  159.         for ( j=0; j < width; j++)
  160.             new_image->content.image.data[i][j] = image[i][j];
  161.     return new_image;
  162. }
  163.  
  164. /*  messageTextCreate(int,const char*)
  165.  Gets a number representing the senderID and a string representing the text
  166.  message. Returns a new message object, or NULL if allocation failed */
  167. Message messageTextCreate(int senderID, const char* text) {
  168.     IF_NULL_RETURN_NULL(text)
  169.     Message newMessage = malloc(sizeof(*newMessage));
  170.     IF_NULL_RETURN_NULL(newMessage)
  171.     newMessage->senderID = senderID;
  172.     newMessage->content.text = copyString(text);
  173.     if (newMessage->content.text == NULL) {
  174.         free(newMessage);
  175.         return NULL;
  176.     }
  177.     newMessage->type = MESSAGE_TEXT;
  178.     return newMessage;
  179. }
  180.  
  181. /*  copyString(const char*)
  182.  Gets a string, copy it to new allocated space.
  183.  Returns a pointer to the new string, or returns NULL if allocation failed */
  184. static char *copyString(const char* inputString) {
  185.     assert(inputString != NULL);
  186.     char *newString = malloc(sizeof(*newString)*(strlen(inputString) + 1));
  187.     IF_NULL_RETURN_NULL(newString)
  188.     strcpy(newString, inputString);
  189.     return newString;
  190. }
  191.  
  192. MessageResult messageIsPalindrome(const Message message, bool* outIsPalindrome) {
  193.     if ( !message )
  194.         return MESSAGE_NULL_ARGUMENT;
  195.     if ( !message->content.text )
  196.         return MESSAGE_NULL_ARGUMENT;
  197.     if ( (message->type) == MESSAGE_IMAGE)
  198.         return MESSAGE_WRONG_TYPE;
  199.     int i;
  200.     char* str = copyString(message->content.text);
  201.     if (str == NULL) {
  202.         return MESSAGE_OUT_OF_MEMORY;
  203.     }
  204.     int j, startNewLine=0;
  205.     (*outIsPalindrome) = true;
  206.     for ( i = 0; str[i] < (strlen(str)+1) ; i++ ) {
  207.         if (str[i] == '\0')
  208.             break;
  209.         if (str[i] == '\n') {
  210.             for ( j = startNewLine; j < i-1; j++) {
  211.                 if (str[j] != str[i-j-1]) {
  212.                     (*outIsPalindrome) = false;
  213.                     break;
  214.                 }
  215.                 startNewLine = i+1;
  216.             }
  217.             if (*outIsPalindrome == false)
  218.                 break;
  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.     int line_counter = 0;
  292.     (*outValue) = str[0];       // TODO: fix getCharacter with blank lines
  293.     for ( int i = 0; str[i] != '\0'; i++ ) {
  294.         if (str[i] == '\n')
  295.             line_counter++;
  296.         if (line_counter == line) {
  297.             int j = 0;
  298.             while ( j != index )
  299.                 j++;
  300.             (*outValue) = str[i+j+line_counter];
  301.             break;
  302.         }
  303.     }
  304.     free(str);
  305.     return MESSAGE_SUCCESS;
  306. }
  307.  
  308. /*  messageInvertColors(Message)
  309.  Gets a message object.
  310.  Inverts the colors of picture's message
  311.  Returns success\error according to specification. */
  312. MessageResult messageInvertColors(Message message) {
  313.     IF_NULL_RETURN_NULL_ARGUMENT(message)
  314.     IF_NULL_RETURN_NULL_ARGUMENT(message->content.image.data)
  315.     IS_WRONG_TYPE(message,MESSAGE_IMAGE)
  316.     for (int i=0; i < message->content.image.height; i++) {
  317.         for (int j=0; j< message->content.image.width; j++) {
  318.             message->content.image.data[i][j]=255-message->content.image.data[i][j];
  319.         }
  320.     }
  321.     return MESSAGE_SUCCESS;
  322. }
  323. /*  messageRotate(Message,Rotation)
  324.  Gets a message object.
  325.  Rotates the message's image by 90 degrees clockwise or anti-clockwise.
  326.  Returns success\error according to specification. */
  327. static MessageResult messageRotate(Message message, Rotation direction) {
  328.     IF_NULL_RETURN_NULL_ARGUMENT(message)
  329.     IF_NULL_RETURN_NULL_ARGUMENT(message->content.image.data)
  330.     IS_WRONG_TYPE(message,MESSAGE_IMAGE)
  331.     // imagePre[heightPre][widthPre]
  332.     unsigned char **imagePre = message->content.image.data; // image before rotation
  333.     int heightPre = message->content.image.height; // image height before rotation
  334.     int widthPre = message->content.image.width; // image width before rotation
  335.     // imagePost[widthPost][heightPost]
  336.     int heightPost = widthPre; // image height after rotation
  337.     int widthPost = heightPre; // image width after rotation
  338.     unsigned char **imagePost = malloc(sizeof(*imagePost)*heightPost);
  339.     if (imagePost == NULL) {
  340.         return MESSAGE_OUT_OF_MEMORY;
  341.     }
  342.     for (int i=0; i < heightPost; i++) {
  343.         imagePost[i] = malloc(sizeof(**imagePost)*widthPost);
  344.         if (imagePost[i] == NULL) {
  345.             for (int j=0; j<i; j++) {
  346.                 free (imagePost[j]);
  347.                 free (imagePost);
  348.             }
  349.             return MESSAGE_OUT_OF_MEMORY;
  350.         }
  351.     }
  352.     for (int i = 0; i < heightPost; i++) {
  353.          for (int j = 0; j < widthPost; j++) {
  354.              imagePost[i][j] = ( (direction == Clockwise) ? imagePre[heightPre-1-j][i] : imagePre[j][widthPre-1-i] );
  355.         }
  356.     }
  357.     message->content.image.data = imagePost;
  358.     message->content.image.height = heightPost;
  359.     message->content.image.width = widthPost;
  360.     for (int i=0;i<heightPre;i++) { // Freeing ImagePre's every string
  361.             free(imagePre[i]);
  362.     }
  363.     free(imagePre); // Freeing the array of strings
  364.     return MESSAGE_SUCCESS;
  365. }
  366.  
  367. /*  messageRotateClockwise(Message)
  368.  Gets a message object.
  369.  Rotates the message's image by 90 degrees clock-wise using messageRotate().
  370.  Returns success\error according to specification. */
  371. MessageResult messageRotateClockwise(Message message) {
  372.     return messageRotate(message,Clockwise);
  373. }
  374.  
  375. /*  messageRotateAntiClockwise(Message)
  376.  Gets a message object.
  377.  Rotates the message's image by 90 degrees counter clock-wise using messageRotate().
  378.  Returns success\error according to specification. */
  379. MessageResult messageRotateAntiClockwise(Message message) {
  380.     return messageRotate(message,Anti_Clockwise);
  381. }
  382.  
  383. MessageResult messageGetColor(const Message message, unsigned row, unsigned
  384.         column, unsigned char* outColor) {
  385.     if ( !message )
  386.         return MESSAGE_NULL_ARGUMENT;
  387.     if (message->type == MESSAGE_TEXT)
  388.         return MESSAGE_WRONG_TYPE;
  389.     if (message->content.image.height < row || message->content.image.width <
  390.             column)
  391.         return MESSAGE_OUT_OF_BOUNDS;
  392.     (*outColor) = message->content.image.data[row][column];
  393.     return MESSAGE_SUCCESS;
  394. }
  395.  
  396. MessageResult messageCompare(const Message message1, const Message message2,
  397.         bool* outIdentical) {
  398.     if ( !message1 || !message2)
  399.         return MESSAGE_NULL_ARGUMENT;
  400.     if (message1->type == message2->type &&
  401.         message1->senderID == message2->senderID) {
  402.         if (message1->type == MESSAGE_IMAGE) {
  403.             for (int i = 0; i < message1->content.image.height; i++) {
  404.                 for (int j = 0; j < message1->content.image.width; j++) {
  405.                     if (message1->content.image.data[i][j] ==
  406.                         message2->content.image.data[i][j]) {
  407.                         (*outIdentical = true);
  408.                     }
  409.                     else (*outIdentical = false);
  410.                 }
  411.             }
  412.         }
  413.         else {
  414.             int len1 = messageLength(message1);
  415.             int len2 = messageLength(message2);
  416.             if (len1 != len2) {
  417.                 (*outIdentical) = false;
  418.             }
  419.             else {
  420.                 int counterIdentical = 0;
  421.                 for (int i = 0; i < len1; i++) {
  422.                     if (message1->content.text[i] == message2->content.text[i])
  423.                         counterIdentical++;
  424.                 }
  425.                 if (counterIdentical == len1)
  426.                     (*outIdentical) = true;
  427.             }
  428.         }
  429.     }
  430.     else (*outIdentical = false);
  431.     return MESSAGE_SUCCESS;
  432. }
  433.  
  434. /*  messageCopy(const Message)
  435.  Gets a message object.
  436.  Returns a copy of the message. */
  437. Message messageCopy(const Message message) {
  438.     IF_NULL_RETURN_NULL(message)
  439.     Message messageCopy = malloc(sizeof(*messageCopy));
  440.     IF_NULL_RETURN_NULL(messageCopy)
  441.     messageCopy->senderID=message->senderID;
  442.     messageCopy->type=message->type;
  443.     switch (messageCopy->type) {
  444.         case MESSAGE_TEXT :
  445.             if (message->content.text == NULL) {
  446.                 free(messageCopy);
  447.                 return NULL;
  448.             }
  449.             char *textCopy = malloc(sizeof(*textCopy) * (strlen(message->content.text)+1));
  450.             if (textCopy == NULL) {
  451.                 free(messageCopy);
  452.                 return NULL;
  453.             }
  454.             strcpy(textCopy,message->content.text);
  455.             messageCopy->content.text=textCopy;
  456.             break;
  457.         case MESSAGE_IMAGE :
  458.             if (message->content.image.data == NULL) {
  459.                 free(messageCopy);
  460.                 return NULL;
  461.             }
  462.             unsigned char **dataCopy = malloc(sizeof(*dataCopy) * message->content.image.height);
  463.             if (dataCopy == NULL) {
  464.                 free(messageCopy);
  465.                 return NULL;
  466.             }
  467.             for (int i = 0; i < message->content.image.height; i++) {
  468.                 dataCopy[i]=malloc(sizeof(**dataCopy)*message->content.image.width);
  469.                 if (dataCopy[i] == NULL) {
  470.                     for (int j=0; j<i; j++) {
  471.                         free(dataCopy[j]);
  472.                     }
  473.                     free(dataCopy);
  474.                     free(messageCopy);
  475.                     return NULL;
  476.                 }
  477.                 for (int j = 0; j < message->content.image.width; j++) {
  478.                     dataCopy[i][j]=message->content.image.data[i][j];
  479.                 }
  480.             }
  481.             messageCopy->content.image.data=dataCopy;
  482.             messageCopy->content.image.width=message->content.image.width;
  483.             messageCopy->content.image.height=message->content.image.height;
  484.     }
  485.     return messageCopy;
  486. }
  487.  
  488. /*  messageDestroy(Message)
  489.  Gets a message object and deletes it. */
  490. void messageDestroy(Message message) {
  491.     switch (message->type) {
  492.         case MESSAGE_TEXT:
  493.             free(message->content.text);
  494.             free(message);
  495.             break;
  496.         case MESSAGE_IMAGE:
  497.             for (int i=0; i < message->content.image.height; i++) {
  498.                 free(message->content.image.data[i]);
  499.             }
  500.             free(message->content.image.data);
  501.             free(message);
  502.             break;
  503.     }
  504. }
  505.  
  506. MessageResult messageGetSenderID(const Message message, int* outSenderID) {
  507.     if ( !message )
  508.                 return MESSAGE_NULL_ARGUMENT;
  509.     (*outSenderID) = message->senderID;
  510.     return MESSAGE_SUCCESS;
  511. }
  512.  
  513. MessageResult messageGetType(const Message message, MessageType* outType) {
  514.     if ( !message )
  515.         return MESSAGE_NULL_ARGUMENT;
  516.     if (message->type == MESSAGE_IMAGE)
  517.         (*outType) = MESSAGE_IMAGE;
  518.     else (*outType) = MESSAGE_TEXT;
  519.     return MESSAGE_SUCCESS;
  520. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement