Guest User

Untitled

a guest
May 29th, 2018
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.59 KB | None | 0 0
  1. /*
  2. Combines two files with byte boundaries.
  3. License: MIT.
  4. */
  5.  
  6. #include <limits.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10.  
  11. size_t copyfilev( FILE *outf, FILE *inf, unsigned char *bufo, const size_t bufs )
  12. {
  13. size_t actr = 0, actw = 0, totr = 0;
  14.  
  15. do
  16. {
  17. actr = fread( bufo, 1, bufs, inf );
  18. actw = fwrite( bufo, 1, actr, outf );
  19. actr &= actw;
  20. totr += actr;
  21. } while ( actr == bufs );
  22.  
  23. return(totr);
  24. }
  25.  
  26. int combin( FILE *arqo, FILE *arqi[2], unsigned char *bufm, const size_t readf[2], const size_t readl, const size_t bufs )
  27. {
  28. int reti = 0;
  29. size_t bufr = bufs, buftr = 0, memloop = 1, mempos = 0, teste = 0, ui = 0;
  30. unsigned char uci = 0;
  31. /* Cap the buffer. */
  32. memloop = bufs / readl;
  33. bufr = memloop * readl;
  34.  
  35. for ( buftr = bufr; buftr == bufr; )
  36. {
  37. buftr = 0;
  38. /* Fill buffer. */
  39. for ( mempos = 0, ui = 0; ui < memloop; ui++ )
  40. {
  41.  
  42. for ( uci = 0; uci < 2; uci++ )
  43. {
  44. teste = fread( &bufm[mempos], 1, readf[uci], arqi[uci] );
  45. buftr += teste;
  46.  
  47. if ( teste != readf[uci] )
  48. {
  49. /* Check for bad combination. */
  50. if ( teste > 0 )
  51. {
  52. reti = 1;
  53. }
  54. break;
  55. }
  56.  
  57. mempos += teste;
  58. }
  59.  
  60. if ( uci != 2 )
  61. {
  62. break;
  63. }
  64.  
  65. }
  66.  
  67. teste = fwrite( bufm, 1, buftr, arqo );
  68. // buftr &= teste;
  69. if ( teste != buftr )
  70. {
  71. reti = 1;
  72. break;
  73. }
  74.  
  75. }
  76.  
  77. #ifdef __DEBUG__
  78. printf( "Bufr: %lu\nBuftr: %lu\nMemloop: %lu\nMempos: %lu\nTeste loop 1: %lu\nUci: %u\n", bufr, buftr, memloop, mempos, teste, uci );
  79. #endif
  80. uci ^= 1;
  81. teste = copyfilev( arqo, arqi[uci], bufm, bufs );
  82. /* Check for bad combination, take two. */
  83. if ( teste > 0 )
  84. {
  85. reti = 1;
  86. }
  87.  
  88. #ifdef __DEBUG__
  89. printf( "Final teste: %lu\n", teste );
  90. #endif
  91. return(reti);
  92. }
  93.  
  94. int main( int argc, char **argv )
  95. {
  96. FILE *arqi[2] = { 0, 0 };
  97. FILE *arqo = 0;
  98. char *errc = '\0', *file1n = '\0', *file2n = '\0', *fileon = '\0';
  99. int i = 0;
  100. size_t readf[2] = { 524288, 524288 };
  101. size_t bufs = 1048576, readl = 1048576, teste = 0;
  102. unsigned char *bufm = 0;
  103. unsigned char uci = 0;
  104.  
  105. for ( ; i != -1; )
  106. {
  107. i = getopt( argc, argv, "1:2:ho:r:" );
  108.  
  109. switch ( i )
  110. {
  111. /* Detects overflow before it is too late. */
  112. case '1':
  113. readf[0] = strtoul( optarg, &errc, 10 );
  114. teste = ULONG_MAX - readf[0];
  115.  
  116. if ( ( errc[0] != '\0' ) || ( teste < readf[1] ) )
  117. {
  118. fprintf( stderr, "Invalid value combination.\n" );
  119. return(1);
  120. }
  121. break;
  122.  
  123. case '2':
  124. readf[1] = strtoul( optarg, &errc, 10 );
  125. teste = ULONG_MAX - readf[1];
  126.  
  127. if ( ( errc[0] != '\0' ) || ( teste < readf[0] ) )
  128. {
  129. fprintf( stderr, "Invalid value combination.\n" );
  130. return(1);
  131. }
  132. break;
  133.  
  134. case 'h':
  135. printf( "%s -1 input1_reads -2 input2_reads -r reading_size -o output -- file1 file2 [output]\n", argv[0] );
  136. return(0);
  137.  
  138. case 'o':
  139. fileon = optarg;
  140. break;
  141.  
  142. case 'r':
  143. bufs = strtoul( optarg, &errc, 10 );
  144.  
  145. if ( errc[0] != '\0' )
  146. {
  147. fprintf( stderr, "Wrong reading buffer value!\n" );
  148. return(1);
  149. }
  150. break;
  151.  
  152. case '?':
  153. if ( file1n == 0 )
  154. {
  155. file1n = argv[optind - 1];
  156. }
  157. else if ( file2n == 0 )
  158. {
  159. file2n = argv[optind - 1];
  160. }
  161. else if ( fileon == 0 )
  162. {
  163. fileon = argv[optind - 1];
  164. }
  165. else
  166. {
  167. fprintf( stderr, "Unknown option \"%c\".\n", optopt );
  168. return(1);
  169. }
  170. break;
  171.  
  172. default:
  173. i = -1;
  174. break;
  175. }
  176.  
  177. }
  178.  
  179. for ( i = optind; i < argc; i++ )
  180. {
  181.  
  182. if ( file1n == 0 )
  183. {
  184. file1n = argv[i];
  185. }
  186. else if ( file2n == 0 )
  187. {
  188. file2n = argv[i];
  189. }
  190. else if ( fileon == 0 )
  191. {
  192. fileon = argv[i];
  193. }
  194. else
  195. {
  196. break;
  197. }
  198.  
  199. }
  200.  
  201. readl = readf[0] + readf[1];
  202.  
  203. if ( bufs < readl )
  204. {
  205. fprintf( stderr, "Reading buffer size must hold at least one reading from each file!\n" );
  206. return(1);
  207. }
  208.  
  209. arqi[0] = fopen( file1n, "rb" );
  210.  
  211. if ( arqi[0] == 0 )
  212. {
  213. fprintf( stderr, "Couldn't open \"%s\"!\n", file1n );
  214. return(1);
  215. }
  216.  
  217. arqi[1] = fopen( file2n, "rb" );
  218.  
  219. if ( arqi[1] == 0 )
  220. {
  221. fprintf( stderr, "Couldn't open \"%s\"!\n", file2n );
  222. return(1);
  223. }
  224.  
  225. if ( fileon != 0 )
  226. {
  227. arqo = fopen( fileon, "wb" );
  228.  
  229. if ( arqo == 0 )
  230. {
  231. fprintf( stderr, "Couldn't open \"%s\"!\n", fileon );
  232. return(1);
  233. }
  234.  
  235. }
  236. else
  237. {
  238. arqo = stdout;
  239. }
  240.  
  241. bufm = (unsigned char *)malloc( sizeof(unsigned char) * bufs );
  242.  
  243. if ( bufm == 0 )
  244. {
  245. fprintf( stderr, "Not enough memory for reading buffer!\n" );
  246. return(2);
  247. }
  248.  
  249. /**/
  250. i = combin( arqo, arqi, bufm, readf, readl, bufs ) * 3;
  251. free(bufm);
  252.  
  253. for ( uci = 0; uci < 2; uci++ )
  254. {
  255. fclose(arqi[uci]);
  256. }
  257.  
  258. if ( fileon != 0 )
  259. {
  260. fclose(arqo);
  261. }
  262.  
  263. return(i);
  264. }
Add Comment
Please, Sign In to add comment