irc_message* create_message(char *prefix, char *command, int command_id, char *params) { irc_message *msg = (irc_message *)calloc(1, sizeof(irc_message)); if(prefix != NULL) { msg->prefix = parse_prefix(prefix); } if(command != NULL) { msg->command = alloc_ptr(command); strcpy(msg->command, command); } if(command_id > 0) { msg->command_id = command_id; } if(params != NULL) { msg->params = alloc_ptr(params); strcpy(msg->params, params); } return msg; }
irc_prefix* create_prefix(char *nick, char *user, char *host) { irc_prefix *ret = (irc_prefix *)calloc(1, sizeof(irc_prefix)); char *buffer = (char *)calloc(513, sizeof(char)); if(nick != NULL) { ret->nick = alloc_ptr(nick); strcpy(ret->nick, nick); strcat(buffer, nick); strcat(buffer, "!"); } if(user != NULL) { ret->user = alloc_ptr(user); strcpy(ret->user, user); strcat(buffer, user); strcat(buffer, "@"); } ret->host = alloc_ptr(host); strcpy(ret->host, host); strcat(buffer, host); ret->raw_prefix = alloc_ptr(buffer); strcpy(ret->raw_prefix, buffer); free(buffer); return ret; }
irc_message* parse_message(char *line) { char *save_pointer; char *part = strtok_r(line, " ", &save_pointer); irc_message *msg = (irc_message *)calloc(1, sizeof(irc_message)); if(part[0] == ':') { msg->prefix = parse_prefix(part); part = strtok_r(NULL, " ", &save_pointer); } uintmax_t num = strtoumax(part, NULL, 10); if(num != 0) { msg->command_id = num; } else { msg->command = alloc_ptr(part); strcpy(msg->command, part); } char* remainder = strtok_r(NULL, "\r", &save_pointer); msg->params = alloc_ptr(remainder); strcpy(msg->params, remainder); return msg; }
/* * mm_realloc - Implemented simply in terms of mm_malloc and mm_free, * but with one added optimization. * * The optimization is that if the block is already at the end of the heap, * sbrk only the extra required size and update the header and footer. * No memcpy call is required and return the pointer that was passed in. */ void *mm_realloc(void *ptr, size_t size) { unsigned blkSize = GET_SIZE(HDRP(ptr)); if (realloc_size(size, 0) < blkSize) { return ptr; } // coalesce with sbrk if (NEXT_BLKP(ptr) == ADD_PTR(mem_heap_hi(), 1)) { unsigned allocSize = realloc_size(size, OVERHEAD) - blkSize; mem_sbrk(allocSize); alloc_ptr(ptr, realloc_size(size, OVERHEAD)); // set allocation before the last block PUT_INT(HDRP(NEXT_BLKP(ptr)), 1); return ptr; } /* // allocate coalesce with next free block // allocate coalesce with prev free block */ void *newptr = mm_malloc((unsigned)size); if (newptr == NULL) return NULL; unsigned cpysize = MIN(blkSize - OVERHEAD, (unsigned)size); memcpy_8(newptr, ptr, cpysize); mm_free(ptr); return newptr; }
/* * mm_malloc - Allocate as an explicit free list. * * This is done using a first fit policy on the minimum size of the block. * The first fitting block may be split up into a smaller free block and an * allocated free block to fit the block requested by malloc. The free block * will precede the allocated block to prevent the need to move pointers. * * If the block does not fit, a new allocated block is created, which may * round the block size up to the nearest power of 2. An "allocated" block is * created at the end to prevent coalescing past the heap end. */ void *mm_malloc(size_t size) { // use malloc_size or fit_size unsigned newsize = fit_size(size); // finger = free_list->next size_t *finger = (size_t *)GET(NEXT_PTR(free_list)); size_t *p = (size_t *)free_list; unsigned fitSize = ~0; // iterate linked list while (finger != free_list) { unsigned blkSize = GET_SIZE(HDRP(finger)); // look for best fit, exit early if perfect fit if (blkSize == newsize) { p = finger; break; } // remember best fit if (blkSize > newsize && blkSize < fitSize) { p = finger; fitSize = blkSize; } // finger = finger->next finger = (size_t *)GET(NEXT_PTR(finger)); } // if block doesn't fit in any free block, allocate more heap space if (p == free_list) { // round up with malloc_size newsize = malloc_size(size); // if block before end of heap is a free block, coalesce void *prevPtr = PREV_BLKP(ADD_PTR(mem_heap_hi(), 1)); if (prevPtr < mem_heap_hi() && !GET_ALLOC(HDRP(prevPtr))) { // calculate new size to sbrk unsigned allocSize = newsize - GET_SIZE(HDRP(prevPtr)); p = mem_sbrk(allocSize); if ((int)(p) == -1) return NULL; // prevPtr->prev->next = prevPtr->next; PUT(NEXT_PTR(GET(PREV_PTR(prevPtr))), GET(NEXT_PTR(prevPtr))); // prevPtr->next->prev = prevPtr->prev; PUT(PREV_PTR(GET(NEXT_PTR(prevPtr))), GET(PREV_PTR(prevPtr))); // allocate prevPtr to new size alloc_ptr(prevPtr, newsize); // set allocation before the last block PUT_INT(HDRP(NEXT_BLKP(prevPtr)), 1); return prevPtr; } p = mem_sbrk(newsize); if ((int)(p) == -1) return NULL; alloc_ptr(p, newsize); // set allocation before the last block PUT_INT(HDRP(NEXT_BLKP(p)), 1); return p; } unsigned freeSize = GET_SIZE(HDRP(p)); if (freeSize - newsize >= FREE_OVERHEAD) { // split free block into free and allocated blocks unsigned header = freeSize - newsize; // header PUT_INT(HDRP(p), header); // footer PUT_INT(FTRP(p), header); p = ADD_PTR(p, freeSize - newsize); } else { // allocate the whole free block newsize = freeSize; // p->prev->next = p->next PUT(NEXT_PTR(GET(PREV_PTR(p))), GET(NEXT_PTR(p))); // p->next->prev = p->prev PUT(PREV_PTR(GET(NEXT_PTR(p))), GET(PREV_PTR(p))); } // sets header and footer with allocate bit set alloc_ptr(p, newsize); return p; }