Advertisement
Broatlas

buffer.c

Sep 29th, 2016
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.17 KB | None | 0 0
  1. #include <stdio.h>  /* standard input/output */
  2. #include <malloc.h> /* for dynamic memory allocation*/
  3. #include <limits.h> /* implementation-defined data type ranges and limits */
  4. #include "buffer.h"
  5.  
  6.  
  7. Buffer * b_create(short init_capacity, char inc_factor, char o_mode){
  8.     /*test parameters*/
  9.     if (init_capacity > SHRT_MAX || init_capacity < 1){
  10.         /*Invaild capacity */
  11.         return NULL;
  12.     }
  13.     if ((o_mode != 'f') && (o_mode != 'm') && (o_mode != 'a')){
  14.         /*not vaild o_mode*/
  15.         return NULL;
  16.     }
  17.  
  18.  
  19.     pBuffer pBD = (Buffer *)calloc(init_capacity, sizeof(Buffer));
  20.     if (pBD == NULL){
  21.         perror("Error");
  22.         return NULL;
  23.     }
  24.     pBD->cb_head = (char *)malloc(init_capacity *sizeof(char));
  25.     if (pBD->cb_head == NULL){
  26.         perror("Error");
  27.         return NULL;
  28.     }
  29.     switch (o_mode)
  30.     {
  31.     case'f':
  32.         pBD->mode = 0;
  33.         pBD->inc_factor = 0;
  34.         break;
  35.     case'a':
  36.         if ((unsigned char)inc_factor > UCHAR_MAX || (unsigned char)inc_factor < 1){
  37.             /*invalid range*/
  38.             b_free(pBD);
  39.             return NULL;
  40.         }
  41.         pBD->mode = 1;
  42.         pBD->inc_factor = inc_factor;
  43.         break;
  44.     case'm':
  45.         if (inc_factor > M_INC_FACTOR_MAX || inc_factor < 1){
  46.             /*invalid range*/
  47.             b_free(pBD);
  48.             return NULL;
  49.         }
  50.         pBD->mode = -1;
  51.         pBD->inc_factor = inc_factor;
  52.         break;
  53.     default:
  54.         return NULL;
  55.         break;
  56.     }
  57.     pBD->addc_offset = 0;
  58.     pBD->eob = 0;
  59.     pBD->getc_offset = 0;
  60.     pBD->capacity = init_capacity;
  61.     return pBD;
  62. }
  63. pBuffer b_addc(pBuffer const pBD, char symbol){
  64.     pBD->r_flag = 0;
  65.  
  66.     /*if function is buffer not at capactiy add the symbol to the char array and incrment the addc_offeset by 1 and return*/
  67.     if (b_isfull(pBD) == 1){
  68.         /*if buffer is full it must be increased depending on operation mode*/
  69.         /*old address*/
  70.         char *old_mem_location = pBD->cb_head;
  71.         if (pBD->mode == 0){
  72.             /*operating mode expected to return null */
  73.             return NULL;
  74.         }
  75.         if (pBD->mode == 1){
  76.             if (pBD->capacity >= SHRT_MAX){
  77.                 /*buffer max size reached return null*/
  78.                 printf("Buffer at maxium Capacity");
  79.                 return NULL;
  80.             }
  81.             /*increase capacity by inc_factor*/
  82.             short temp_inc_factor = (unsigned char)pBD->inc_factor;
  83.             if ((pBD->capacity + temp_inc_factor) >= SHRT_MAX){
  84.                 pBD->capacity = SHRT_MAX;
  85.             }
  86.             else{
  87.                 pBD->capacity = pBD->capacity + temp_inc_factor;
  88.             }
  89.            
  90.         }
  91.         if (pBD->mode == -1){
  92.            
  93.             if (pBD->capacity >= SHRT_MAX){
  94.                 /*buffer max size reached return null*/
  95.                 printf("Buffer at maxium Capacity");
  96.                 return NULL;
  97.             }
  98.             short space_left = SHRT_MAX - pBD->capacity;
  99.             /*don't need to cast in mode -1 max values are 1 to 100*/
  100.             short temp_inc_factor = space_left * pBD->inc_factor / 100;
  101.  
  102.             if (temp_inc_factor <= 0 || ((temp_inc_factor + pBD->capacity) >= SHRT_MAX)){
  103.                 pBD->cb_head = realloc(pBD->cb_head, (SHRT_MAX *sizeof(char)));
  104.                 pBD->capacity = SHRT_MAX;
  105.             }
  106.             else {
  107.                 /*increase the capacity*/
  108.                 pBD->capacity += temp_inc_factor;
  109.             }
  110.         }
  111.         /*Try to expand the memory*/
  112.        
  113.         pBD->cb_head = (char *)realloc(pBD->cb_head, (pBD->capacity *sizeof(char)));
  114.         if (pBD->cb_head == NULL){
  115.             return NULL;
  116.         }
  117.         if (old_mem_location != pBD->cb_head){
  118.             /*If realloc moved the memory location set r_flag to 1*/
  119.             pBD->r_flag = SET_R_FLAG;
  120.         }
  121.        
  122.     }
  123.     /*Add the symbol to the  cb_head array*/
  124.             pBD->cb_head[pBD->addc_offset] = symbol;
  125.             pBD->addc_offset++;
  126.             return pBD;
  127. }
  128.  
  129. int b_reset(Buffer* const pBD){
  130.     if (pBD == NULL){
  131.         return R_FAIL1;
  132.     }
  133.     /*will allow char array to be overwritten*/
  134.     pBD->addc_offset = 0;
  135.     if (pBD->addc_offset != 0){
  136.         /*failed to set property*/
  137.         return R_FAIL1;
  138.     }
  139.     return 0;
  140. }
  141. void b_free(Buffer* const pBD){
  142.     free(pBD->cb_head);
  143.     free(pBD);
  144. }
  145. int b_isfull(Buffer* const pBD){
  146.     if (pBD == NULL){
  147.         /*Run time Error*/                                                                                                                                            
  148.         return R_FAIL1;
  149.     }
  150.     if (pBD->addc_offset == pBD->capacity){
  151.         /*Buffer is full*/
  152.         pBD->eob = 1;
  153.         return 1;
  154.     }
  155.     pBD->eob = 0;
  156.     return 0;
  157. }
  158. short b_size(Buffer * const pBD){
  159.     if (pBD == NULL){
  160.         return R_FAIL1;
  161.     }
  162.     return(pBD->addc_offset);
  163. }
  164. short b_capacity(Buffer * const pBD){
  165.     if (pBD == NULL){
  166.         return R_FAIL1;
  167.     }
  168.     return pBD->capacity;
  169. }
  170. short b_setmark(Buffer * const pBD, short mark){
  171.     if (pBD == NULL || mark > pBD->addc_offset){
  172.         return R_FAIL1;
  173.     }
  174.     pBD->mark_offset = mark;
  175.  
  176.     return 0;
  177. }
  178. short b_mark(Buffer * const pBD){
  179.     if (pBD == NULL){
  180.         return R_FAIL1;
  181.     }
  182.  
  183.     return pBD->mark_offset;
  184. }
  185. int b_mode(Buffer * const pBD){
  186.     if (pBD == NULL){
  187.         return R_FAIL1;
  188.     }
  189.     return (int)pBD->mode;
  190. }
  191. size_t b_incfactor(Buffer * const pBD){
  192.     if (pBD == NULL){
  193.         return 256;
  194.     }
  195.    
  196.     return (unsigned char)pBD->inc_factor;
  197. }
  198. int b_load(FILE * const fi, Buffer * const pBD){
  199.     /* if the current character cannot be put in the buffer, the */
  200.     int input;
  201.     while (1)
  202.     {
  203.         input = fgetc(fi);
  204.        
  205.         if (feof(fi) || input == -1)
  206.         {
  207.             return 0;
  208.         }
  209.         if (b_addc(pBD, (char)input) == NULL){
  210.             return LOAD_FAIL;
  211.         }
  212.  
  213.     }
  214.     return 0;
  215. }
  216. int b_isempty(Buffer * const pBD){
  217.     if (pBD == NULL){
  218.         return R_FAIL1;
  219.     }
  220.     if (pBD->addc_offset > 0){
  221.         return 1;
  222.     }
  223.     return 0;
  224.     }
  225. int b_eob(Buffer * const pBD){
  226.     if (pBD == NULL){
  227.         return R_FAIL1;
  228.     }
  229.     return pBD->eob;
  230. }
  231. char b_getc(Buffer * const pBD){
  232.     if (pBD == NULL){
  233.         return R_FAIL2;
  234.     }
  235.     if (pBD->getc_offset == pBD->addc_offset){
  236.         pBD->eob = 1;
  237.         return R_FAIL1;
  238.     }
  239.     short offset_preincrement = pBD->getc_offset;
  240.     pBD->eob = 0;
  241.     pBD->getc_offset++;
  242.  
  243.     return (unsigned char)pBD->cb_head[offset_preincrement];
  244. }
  245. int b_print(Buffer * const pBD){
  246.     if (pBD == NULL){
  247.         return R_FAIL1;
  248.     }
  249.     if (b_isempty(pBD) == 0){
  250.         printf("The Buffer is empty\n");
  251.         return 0;
  252.     }
  253.     short temp = pBD->getc_offset;
  254.     short count = 0;
  255.     char letter;
  256.     pBD->getc_offset = 0;
  257.     while (pBD->eob != 1){
  258.         letter = b_getc(pBD);
  259.         if (letter >= EOF){
  260.             printf("%c", letter);
  261.         }
  262.         count++;
  263.     }
  264.     printf("\n");
  265.     pBD->getc_offset = temp;
  266.     return count;
  267. }
  268. Buffer *b_pack(Buffer * const pBD){
  269.     if (pBD == NULL){
  270.         return NULL;
  271.     }
  272.     if (pBD->eob == 1){
  273.         /*Buffer is already at the full althought you may want to expand mem here*/
  274.         return pBD;
  275.     }
  276.     short new_capacity = pBD->addc_offset + 1;
  277.     char * temp = pBD->cb_head;
  278.  
  279.     pBD->cb_head = (char*)realloc(pBD->cb_head, (new_capacity * sizeof(char)));
  280.    
  281.     if (temp != pBD->cb_head){
  282.         /*memory had been reloacted*/
  283.         pBD->r_flag = 1;
  284.     }
  285.  
  286.     pBD->capacity = new_capacity;
  287.    
  288.     return pBD;
  289.  
  290. }
  291. char b_rflag(Buffer *const pBD){
  292.     if (pBD == NULL){
  293.         return R_FAIL1;
  294.     }
  295.     return pBD->r_flag;
  296. }
  297. short b_retract(Buffer * const pBD){
  298.     if (pBD == NULL){
  299.         return R_FAIL1;
  300.     }
  301.     if (pBD->getc_offset == 0){
  302.         return pBD->addc_offset;
  303.     }
  304.     pBD->getc_offset--;
  305.     return pBD->getc_offset;
  306. }
  307. short b_retract_to_mark(Buffer * const pBD){
  308.     if (pBD == NULL){
  309.         return R_FAIL1;
  310.     }
  311.     if (pBD->getc_offset == pBD->mark_offset){
  312.         return pBD->getc_offset;
  313.     }
  314.     pBD->getc_offset = pBD->mark_offset;
  315.     return pBD->getc_offset;
  316. }
  317. short b_getcoffset(Buffer * const pBD){
  318.     if (pBD == NULL){
  319.         return R_FAIL1;
  320.     }
  321.     return pBD->getc_offset;
  322. }
  323. char * b_cbhead(Buffer * const pBD){
  324.  
  325.     if (pBD == NULL){
  326.         return NULL;
  327.     }
  328.  
  329.     return pBD->cb_head;
  330.    
  331. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement