Advertisement
homer512

Mash's question

Apr 15th, 2014
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.45 KB | None | 0 0
  1. #include <stdio.h>
  2. /* using fprintf, fread, fwrite, fopen, fclose */
  3. #include <ctype.h>
  4. /* using isxdigit */
  5.  
  6. static const char* LOG_FILE = "LogFile_ProxyBufferContents_FJ_small.html";
  7. static const char* OUT_FILE = "LogFile_ProxyBufferContents_FJ_small_out.html";
  8.  
  9. /*4096 would be a better size*/
  10. #define BUF_SIZE 200
  11.  
  12. /**
  13.  * Searches for CRNL line endings
  14.  *
  15.  * \param buf input data
  16.  * \param size length of buf
  17.  * \return The position of the next CR, followed by an NL. -1 if none is found
  18.  */
  19. static int find_crnl(const char* buf, int size)
  20. {
  21.   for(const char* pos = buf; size > 1; ++pos, --size)
  22.     if(pos[0] == '\r') {
  23.       if(pos[1] == '\n')
  24.     return pos - buf;
  25.       else
  26.     fprintf(stderr, "Unexpected CR line ending\n");
  27.     }
  28.   return -1;
  29. }
  30.  
  31. /**
  32.  * Checks whether the given string is a hex number
  33.  *
  34.  * \param buf input data
  35.  * \param size length of string in buf that shall be checked
  36.  * \return 1 if buf is a valid hex number, 0 otherwise
  37.  */
  38. static int is_hex(const char* buf, int size)
  39. {
  40.   if(! size)
  41.     return 0;
  42.   for(int i = 0; i < size; ++i)
  43.     if(! isxdigit(buf[i]))
  44.       return 0;
  45.   return 1;
  46. }
  47.  
  48. /**
  49.  * Writes a line from input to output unless it is just a hex number
  50.  *
  51.  * \param buf input data. Is assumed to start at new line (after CRNL or at
  52.  * beginning of file
  53.  * \param size bytes in buf
  54.  * \param out output buffer. Will be overwritten. Must be at least size bytes
  55.  * large
  56.  * \param written Number of bytes in out after function returns. Is not
  57.  * initialized with 0. Is just incremented
  58.  * \return Start of next line or -1 if no end could be found
  59.  */
  60. static int filter_line(const char* buf, int size, char* out, int* written)
  61. {
  62.   int line_end = find_crnl(buf, size);
  63.   if(line_end < 0)
  64.     return line_end;
  65.   if(is_hex(buf, line_end)) {
  66.     fprintf(stderr, "Skipping hex\n");
  67.     return line_end + 2; /* skip */
  68.   }
  69.   for(int i = 0; i < line_end + 2; ++i, ++(*written))
  70.     out[i] = buf[i]; /* copy */
  71.   return line_end + 2;
  72. }
  73.  
  74. /**
  75.  * Repeatedly calls filter_line for buffer that may contain multiple lines
  76.  *
  77.  * \param buf input data. Is assumed to start at new line (after CRNL or at
  78.  * beginning of file
  79.  * \param size byte in buf
  80.  * \param out output buffer. Will be overwritten. Must be at least size bytes
  81.  * large
  82.  * \param written Number of bytes in out after function returns. Will be
  83.  * initialized with 0
  84.  * \return number of bytes processed. Remainder contains no complete line
  85.  */
  86. static int filter_buf(const char* buf, int size, char* out, int* written)
  87. {
  88.   const char* pos = buf;
  89.   *written = 0;
  90.   for(;;) {
  91.     int next_start = filter_line(pos, size, out + *written, written);
  92.     if(next_start < 0)
  93.       return pos - buf;
  94.     pos += next_start;
  95.     size -= next_start;
  96.   }
  97. }
  98.  
  99. /**
  100.  * Calls filter_buf for file input/output and handles the remainder
  101.  *
  102.  * \param input file opened for reading
  103.  * \param output file opened for writing
  104.  * \param in_buf buffer of at least BUF_SIZE length, may contain unprocessed
  105.  * data after return
  106.  * \param in_pos number of unprocessed bytes in in_buf from last call
  107.  * \return number of unprocessed bytes in in_buf or -1 on EOF
  108.  */
  109. static int filter_fbuf(FILE* input, FILE* output, char* in_buf, int in_pos)
  110. {
  111.   char out_buf[BUF_SIZE];
  112.   int size = fread(in_buf + in_pos, 1, BUF_SIZE - in_pos, input);
  113.   size += in_pos;
  114.   if(! size)
  115.     return -1;
  116.   int written;
  117.   int end_pos = filter_buf(in_buf, size, out_buf, &written);
  118.   if(end_pos) {
  119.     for(int i = 0; i < size - end_pos; ++i)
  120.       in_buf[i] = in_buf[i + end_pos];
  121.   }
  122.   else {
  123.     if(size == BUF_SIZE) {
  124.       fprintf(stderr, "Line too long\n");
  125.       fwrite(in_buf, 1, size, output);
  126.       return 0;
  127.     }
  128.     else {
  129.       /* no newline at EOF */
  130.       filter_line(in_buf, size, out_buf, &written);
  131.     }
  132.   }
  133.   fwrite(out_buf, 1, written, output);
  134.   return size - end_pos;
  135. }
  136.  
  137. /**
  138.  * Repeatedly calls filter_fbuf until the whole input file is processed
  139.  *
  140.  * \param input file opened for reading
  141.  * \param output file opened for writing
  142.  */
  143. static void filter_file(FILE* input, FILE* output)
  144. {
  145.   char in_buf[BUF_SIZE];
  146.   int in_pos = 0;
  147.   do {
  148.     in_pos = filter_fbuf(input, output, in_buf, in_pos);
  149.   } while(in_pos >= 0);
  150. }
  151.  
  152. int main(void)
  153. {
  154.   FILE* input = fopen(LOG_FILE, "r");
  155.   if(! input)
  156.     return 1;
  157.   FILE* output = fopen(OUT_FILE, "w");
  158.   if(! output)
  159.     return 1;
  160.   filter_file(input, output);
  161.   fclose(output);
  162.   fclose(input);
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement