sta-s2z

Untitled

Jul 25th, 2019
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.62 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5.  
  6. typedef struct s_result
  7. {
  8. long sqsize;
  9. long sqx;
  10. long sqy;
  11. long sqline;
  12. } t_result;
  13.  
  14. typedef struct s_filereader
  15. {
  16. int fd;
  17. char * fbuf;
  18. char * filename;
  19. long fsize;
  20. long lines;
  21. long linelen;
  22. long firstcrpos;
  23. char * linebuf;
  24. long bytesread;
  25. char cobs;
  26. char cfree;
  27. char cfill;
  28. } t_filereader;
  29.  
  30. typedef struct s_square_finder
  31. {
  32. long pos;
  33. long is_square;
  34. long size;
  35. } t_finder;
  36.  
  37. int print_error (void) {
  38. size_t ret;
  39. ret = write(1, "map error\n", 10);
  40. if (ret != 10)
  41. return print_error();
  42. return -1;
  43. }
  44.  
  45. inline long pw(long number, int pw)
  46. {
  47. long newnumber;
  48. int count;
  49. newnumber = 1;
  50. if (pw == 0)
  51. return 1;
  52. count = 0;
  53. while (count < pw)
  54. {
  55. newnumber *= number;
  56. count++;
  57. }
  58. return newnumber;
  59. }
  60.  
  61. long filesize_cr(char * filename, long *crpos)
  62. {
  63. char buf[300000];
  64. int fd;
  65. unsigned long c;
  66. unsigned long fs;
  67. unsigned long size;
  68. fs = 0;
  69. size = 1;
  70. *crpos = -1;
  71. if ((fd = open(filename, O_RDONLY)) == -1)
  72. return (-1);
  73. while (size > 0)
  74. {
  75. size = read(fd, &buf, sizeof(buf));
  76. if (*crpos == -1)
  77. {
  78. c = 0;
  79. while (c < size)
  80. {
  81. if ((buf[c] == '\n') && (*crpos == -1))
  82. *crpos = (long)fs + c;
  83. c++;
  84. }
  85. }
  86. fs += size;
  87. }
  88. close(fd);
  89. return fs;
  90. }
  91.  
  92. int dump_stdin(char * filename)
  93. {
  94. char buf[300000];
  95. int fo;
  96. long size;
  97. size_t ret;
  98. size = 1;
  99. if ((fo = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0777)) == -1)
  100. return (-1);
  101. while ((size = read(0, &buf, sizeof(buf))) > 0) {
  102. ret = write(fo, &buf, size);
  103. if ((long) ret != size)
  104. return (-1);
  105. }
  106. close(fo);
  107. return 0;
  108. }
  109.  
  110. inline void find_largest_square(long *histo, t_result *t, long len, long nlen)
  111. {
  112. long i;
  113. t_finder f;
  114. f.pos = 0;
  115. while (f.pos < len)
  116. {
  117. f.size = histo[f.pos];
  118. while (f.size > t->sqy)
  119. {
  120. f.is_square = nlen - (f.pos + f.size);
  121. i = f.pos;
  122. while ((f.is_square >= 0) && (i < f.pos + f.size))
  123. {
  124. f.is_square = histo[i] - f.size;
  125. i++;
  126. }
  127. if ((f.is_square >= 0) && (f.size > t->sqy))
  128. {
  129. t->sqx = f.pos;
  130. t->sqy = f.size;
  131. }
  132. f.size--;
  133. }
  134. f.pos++;
  135. }
  136. t->sqsize = t->sqy * t->sqy;
  137. }
  138.  
  139. int count_line_length(t_filereader *file, long offset)
  140. {
  141. long cpow = 0;
  142. long i;
  143. cpow = 0;
  144. i = offset;
  145. file->lines = 0;
  146. while (i >= 0) /* atoi */
  147. {
  148. if (file->fbuf[i] > '9' || file->fbuf[i] < '0')
  149. return -1;
  150. file->lines += (file->fbuf[i] - '0') * pw(10, cpow);
  151. cpow++;
  152. i--;
  153. }
  154. return 0;
  155. }
  156.  
  157. int process_header(t_filereader *file)
  158. {
  159. char temp;
  160. file->fbuf = (char *)malloc(file->firstcrpos * sizeof(char) + 1);
  161. file->bytesread = read(file->fd, file->fbuf, file->firstcrpos * sizeof(char));
  162. if (((unsigned long)file->bytesread != file->firstcrpos * sizeof(char)) || (file->bytesread < 4))
  163. return print_error();
  164. file->fbuf[file->bytesread] = '\0';
  165. file->cfill = file->fbuf[file->bytesread - 1];
  166. file->cobs = file->fbuf[file->bytesread - 2];
  167. file->cfree = file->fbuf[file->bytesread - 3];
  168. file->fbuf[file->bytesread - 3] = '\0';
  169. if (count_line_length(file, file->bytesread - 4) == -1)
  170. return print_error();
  171. file->linelen = ((file->fsize - file->bytesread) / file->lines) - 1;
  172. free(file->fbuf);
  173. file->bytesread = read(file->fd, &temp, sizeof(char));
  174. if (temp != '\n')
  175. return print_error();
  176. return 0;
  177. }
  178. int file_open(t_filereader * file, char * filename)
  179. {
  180. file->filename = filename;
  181. file->firstcrpos = 0;
  182. file->fsize = filesize_cr(file->filename, &file->firstcrpos);
  183. if (file->fsize == -1)
  184. return print_error();
  185. if ((file->fd = open(file->filename, O_RDONLY)) == -1)
  186. return print_error();
  187. return 0;
  188. }
  189.  
  190. int file_open_stdin(t_filereader * file, char * filename)
  191. {
  192. if (dump_stdin(filename) == -1)
  193. return print_error();
  194. file->filename = filename;
  195. file->firstcrpos = 0;
  196. file->fsize = filesize_cr(filename, &file->firstcrpos);
  197. if (file->fsize == -1)
  198. return print_error();
  199. if ((file->fd = open(file->filename, O_RDONLY)) == -1)
  200. return print_error();
  201. return 0;
  202. }
  203.  
  204. inline void assign_result(t_result *res, t_result *temp_res, long line)
  205. {
  206. if (res->sqsize < temp_res->sqsize)
  207. {
  208. res->sqsize = temp_res->sqsize;
  209. res->sqx = temp_res->sqx;
  210. res->sqy = temp_res->sqy;
  211. res->sqline = line;
  212. }
  213. }
  214.  
  215. inline void prepare_temp_result(t_result *tres, long initvalue) {
  216. tres->sqsize = 0;
  217. tres->sqx = 0;
  218. tres->sqy = initvalue;
  219. return;
  220. }
  221.  
  222. inline void clear_result(t_result *res)
  223. {
  224. res->sqx = 0;
  225. res->sqy = 0;
  226. res->sqsize = 0;
  227. res->sqline = 0;
  228. }
  229.  
  230. int buffer_line (t_filereader *file)
  231. {
  232. file->bytesread = read(file->fd, file->fbuf, file->linelen + 1);
  233. if ((file->fbuf[file->linelen] != '\n') || (file->bytesread != file->linelen + 1))
  234. return print_error();
  235. return 0;
  236. }
  237.  
  238. void clear_histogram(long * h, long length)
  239. {
  240. long i;
  241. i = 0;
  242. while (i < length)
  243. {
  244. h[i] = 0;
  245. i++;
  246. }
  247. }
  248.  
  249. inline int fill_histogram(t_filereader *file, long *histo, long *lasthisto)
  250. {
  251. long i;
  252. i = 0;
  253. while (i < file->linelen)
  254. {
  255. if ((file->fbuf[i] != file->cobs) && (file->fbuf[i] != file->cfree))
  256. return print_error();
  257. if (file->fbuf[i] == file->cobs)
  258. histo[i] = 0;
  259. if (file->fbuf[i] == file->cfree)
  260. histo[i] = lasthisto[i] + 1;
  261. lasthisto[i] = histo[i];
  262. i++;
  263. }
  264. return 0;
  265. }
  266.  
  267. inline int process_map(t_filereader *file, t_result * res)
  268. {
  269. long *histo;
  270. long *lasthisto;
  271. t_result tres;
  272. long i;
  273. i = 0;
  274. lasthisto = (long *)malloc(file->linelen * sizeof(long));
  275. clear_histogram(lasthisto, file->linelen);
  276. while (i < file->lines)
  277. {
  278. file->fbuf = (char *)malloc(file->linelen + 1);
  279. if (buffer_line(file) == -1)
  280. return print_error();
  281. file->fbuf[file->linelen] = '\0';
  282. histo = (long *)malloc(file->linelen * sizeof(long));
  283. if (fill_histogram(file, histo, lasthisto) == -1)
  284. return print_error();
  285. free(file->fbuf);
  286. prepare_temp_result(&tres, res->sqy);
  287. find_largest_square(histo, &tres, file->linelen - tres.sqy, file->linelen);
  288. free(histo);
  289. assign_result(res, &tres, i);
  290. i++;
  291. }
  292. free(lasthisto);
  293. return 0;
  294. }
  295.  
  296. void skip_header (t_filereader *file)
  297. {
  298. file->fbuf = (char *)malloc(file->firstcrpos * sizeof(char) + 1);
  299. file->bytesread = read(file->fd, file->fbuf, file->firstcrpos * sizeof(char) + 1);
  300. free(file->fbuf);
  301. }
  302.  
  303. int print_result (t_filereader *file, t_result *res) {
  304. long i;
  305. long j;
  306. size_t ret;
  307. if ((file->fd = open(file->filename, O_RDONLY)) == -1)
  308. return print_error();
  309. skip_header(file);
  310. i = 0;
  311. while (i < file->lines)
  312. {
  313. file->fbuf = (char *)malloc((file->linelen + 1) * sizeof(char));
  314. file->bytesread = read(file->fd, file->fbuf, file->linelen + 1);
  315. if ((file->fbuf[file->linelen] != '\n') || (file->bytesread != file->linelen + 1))
  316. return print_error();
  317. j = 0;
  318. while (j < file->linelen)
  319. {
  320. if ((i > res->sqline - res->sqy) && (i <= res->sqline) && (j >= res->sqx) && (j < res->sqx + res->sqy))
  321. file->fbuf[j] = file->cfill;
  322. j++;
  323. }
  324. ret = write(1, file->fbuf, file->linelen + 1);
  325. if ((long) ret != file->linelen + 1)
  326. return print_error();
  327. free(file->fbuf);
  328. i++;
  329. }
  330. close(file->fd);
  331. return 0;
  332. }
  333.  
  334. void run_stdin(t_filereader * file, t_result * res, char * filename)
  335. {
  336. size_t ret;
  337. if (file_open_stdin(file, filename) != -1)
  338. if (process_header(file) != -1)
  339. {
  340. clear_result(res);
  341. if (process_map(file, res) != -1)
  342. {
  343. close(file->fd);
  344. print_result(file, res);
  345. }
  346. }
  347. ret = write(1, "\n", 1);
  348. if (ret != 1) {
  349. print_error();
  350. return;
  351. }
  352. return;
  353. }
  354. void run_files(t_filereader * file, t_result * res, char ** av, int ac)
  355. {
  356. int i;
  357. size_t ret;
  358. i = 1;
  359. while (i < ac) {
  360. if (file_open(file, av[i]) != -1)
  361. {
  362. if (process_header(file) != -1)
  363. {
  364. clear_result(res);
  365. if (process_map(file, res) != -1)
  366. {
  367. close(file->fd);
  368. print_result(file, res);
  369. }
  370. }
  371. }
  372. ret = write(1, "\n", 1);
  373. if (ret != 1) {
  374. print_error();
  375. return;
  376. }
  377. i++;
  378. }
  379. return;
  380. }
  381.  
  382. int main(int argc, char **argv)
  383. {
  384. t_result res;
  385. t_filereader file;
  386. if (argc <= 1)
  387. run_stdin(&file, &res, "bsq.tmp");
  388. else
  389. run_files(&file, &res, argv, argc);
  390. }
Advertisement
Add Comment
Please, Sign In to add comment