fork download
  1. #include <stdio.h>
  2. #include <string.h> // strncpy
  3.  
  4. #include <stdlib.h> //exit
  5. #include <ctype.h> // isspace
  6. #include <stdint.h> // uint32_t
  7. #include <math.h> // round
  8.  
  9. #include <string> //std::string
  10. #include <vector> //std::vector
  11.  
  12. //#define BUF_SIZE 15 // 512 bype
  13. //#define BUF_SIZE 512 // 512 bype
  14. //#define BUF_SIZE 1024 // 1KB
  15. //#define BUF_SIZE 1024 * 1024 // 1MB
  16. #define BUF_SIZE 1024 * 1024 * 8 // 8MB
  17. //#define BUF_SIZE 1024 * 1024 *16 // 16MB
  18.  
  19. #define LINE_SIZE 1024 * 2
  20. #define NAME_SIZE 128
  21.  
  22. //#define IS_PRINT true
  23. #define IS_PRINT false
  24.  
  25. #define READ_MODE 0 // 0=fread only, 1=read_data()関数のみ, それ以上=read_data() & 解析
  26.  
  27. typedef enum __TYPE {
  28. TYPE_x,
  29. TYPE_y
  30. } TYPE;
  31.  
  32. //--------------------------------------------------------------------------------
  33. typedef struct __tag_qq_db {
  34. char qq_name[NAME_SIZE];
  35. } t_qq_db;
  36. typedef struct __tag_elem_db {
  37. TYPE type;
  38. unsigned int no;
  39. unsigned int num_line_count;
  40. t_qq_db qq_db;
  41. std::vector<double> numbers;
  42. } t_elem_db;
  43. typedef struct __tag_section_db {
  44. char name[NAME_SIZE];
  45. unsigned int num_1;
  46. unsigned int num_2;
  47. unsigned int text_line_count;
  48. std::vector<std::string> texts;
  49. } t_section_db;
  50. typedef struct __tag_read_db {
  51. char header_name[NAME_SIZE];
  52. unsigned int mag;
  53. } t_read_db;
  54. //--------------------------------------------------------------------------------
  55. struct CCC {
  56. FILE *fp;
  57. unsigned char real_data[BUF_SIZE+1];
  58. unsigned char* data;
  59. unsigned char* temp_data;
  60.  
  61. t_section_db* p_current_section_db;
  62. t_elem_db* p_current_elem_db;
  63.  
  64. t_read_db read_db;
  65.  
  66. bool initialize();
  67. bool read(char* file_path);
  68. size_t read_data();
  69. bool get_header();
  70. bool get_section_name();
  71. bool get_section_index();
  72. bool get_text();
  73. bool get_elem_index();
  74. bool get_elem_qq();
  75. bool get_elem_x(unsigned int i);
  76. bool get_elem_y(unsigned int i);
  77. };
  78. //--------------------------------------------------------------------------------
  79. bool CCC::initialize(){
  80. real_data[BUF_SIZE] = '\x00'; //最後はかならずNULLになるようにセット
  81. data = real_data;
  82. return true;
  83. }
  84. size_t CCC::read_data(){
  85. size_t size = 0;
  86. if( *data == '\x00' ){
  87. size = fread( &real_data, sizeof(real_data[0]), BUF_SIZE, fp);
  88. data = real_data;
  89. // 終端処理。最大値で取得されてなければそこを末尾にする
  90. if( size != BUF_SIZE ) data[size] = '\x00';
  91. // 取得bufの最後尾が改行でなければfpを改行まで戻す
  92. if( data[size-1] != '\x0a' ){
  93. int newline_index = -2;
  94. for(; data[size+newline_index] != '\x0a'; --newline_index);
  95. fseek(fp,newline_index+1,SEEK_CUR);
  96. // bufの最後の改行の次にx00(null)を入れてそれ以降をカット
  97. data[size+newline_index+1] = '\x00';
  98. }
  99. }
  100. return size;
  101. }
  102. // 32=空白
  103. // 0a=改行
  104. // 00=null
  105.  
  106. bool CCC::get_section_name(){
  107. read_data();
  108. temp_data = data;
  109. for(; *++data != '\x0a'; );
  110.  
  111. memcpy(p_current_section_db->name, temp_data, data-temp_data);
  112. p_current_section_db->name[data-temp_data] = '\x00';
  113.  
  114. ++data;
  115. IS_PRINT == true && printf("%s\n", p_current_section_db->name);
  116. return true;
  117. }
  118. bool CCC::get_section_index(){
  119. read_data();
  120. t_section_db section_db;
  121. //数値グループ数を取得
  122. auto func1 = [&](unsigned int* num) {
  123. unsigned int n = 0;
  124. do {
  125. unsigned char ch = (unsigned char)(*data++ - '0');
  126. if (ch <= 9) {
  127. n = n * 10 + ch;
  128. } else {
  129. break;
  130. }
  131. } while (true);
  132. *num = n;
  133. };
  134. func1(&p_current_section_db->num_1);
  135. func1(&p_current_section_db->num_2);
  136. func1(&p_current_section_db->text_line_count);
  137. if( p_current_section_db->num_1 != p_current_section_db->num_2 ){
  138. printf("num_1, num_2の数が違う!!解析する!! %d %d\n", p_current_section_db->num_1, p_current_section_db->num_2);
  139. printf("%s\n", data);
  140. exit(1);
  141. }
  142.  
  143. if( IS_PRINT == false ){
  144. // 日付を捨てる
  145. for(; *data++ != '\x0a'; );
  146. }else{
  147. printf("%d %d %d ", p_current_section_db->num_1, p_current_section_db->num_2, p_current_section_db->text_line_count);
  148. printf("%c", data[0]);
  149. for(; *data++ != '\x0a'; ){
  150. printf("%c", data[0]);
  151. }
  152. }
  153. return true;
  154. }
  155.  
  156. bool CCC::get_text(){
  157. read_data();
  158. temp_data = data;
  159. for(; *++data != '\x0a'; );
  160.  
  161. char line[LINE_SIZE];
  162.  
  163. memcpy(line, temp_data, data-temp_data);
  164. line[data-temp_data] = '\x00';
  165. IS_PRINT == true && printf("%s\n", line);
  166.  
  167. ++data;
  168. return true;
  169. }
  170. bool CCC::get_elem_index(){
  171. read_data();
  172.  
  173. //数値グループ数を取得
  174. auto func1 = [&](unsigned int* num) {
  175. unsigned int n = 0;
  176. do {
  177. unsigned char ch = (unsigned char)(*data++ - '0');
  178. if (ch <= 9) {
  179. n = n * 10 + ch;
  180. } else {
  181. break;
  182. }
  183. } while (true);
  184. *num = n;
  185. };
  186.  
  187. // 数値グループ取得開始
  188. // 78=x, 79=y
  189. if( *data == '\x78' ){
  190. p_current_elem_db->type = TYPE_x;
  191. }else if ( *data == '\x79' ){
  192. p_current_elem_db->type = TYPE_y;
  193. }else{
  194. printf("## ERROR 102 ##\n");
  195. printf("%s\n", data);
  196. exit(1);
  197. }
  198. data+=2;
  199. func1(&p_current_elem_db->no);
  200. func1(&p_current_elem_db->num_line_count);
  201.  
  202. IS_PRINT == true && printf("%c %d %d\n", p_current_elem_db->type == TYPE_x ? 'x' : 'y', p_current_elem_db->no, p_current_elem_db->num_line_count);
  203. return true;
  204. }
  205. bool CCC::get_elem_qq(){
  206. read_data();
  207. // 51=Q,
  208. if( *data == '\x51' ){
  209. // テストなのでとりあえずQQ行はスキップ
  210. if( IS_PRINT == false ){
  211. for(; *data++ != '\x0a'; );
  212. }else{
  213. printf("%c", data[0]);
  214. for(; *data++ != '\x0a'; ){
  215. printf("%c", data[0]);
  216. }
  217. }
  218. }else if( *data == '\x2d' || *data == '\x30' || *data == '\x31' || *data == '\x32' || *data == '\x33' || *data == '\x34' || *data == '\x35' || *data == '\x36' || *data == '\x37' || *data == '\x38' || *data == '\x39' || *data == '\x00'){
  219. // 2d=マイナス記号(-), 30~39=数字, 00=NULL, の時はスルー
  220. }else{
  221. printf("????\n");
  222. printf("%02x\n", *data);
  223. exit(1);
  224. }
  225. return true;
  226. }
  227. bool CCC::get_elem_x(unsigned int i){
  228. read_data();
  229. //係数掛けで数値取得
  230. // auto func2 = [&](double* num) {
  231. auto func2 = [&](unsigned int i) {
  232. uint64_t n = 0;
  233. bool is_minus = false;
  234. do {
  235. // 2d=マイナス記号(-)
  236. if( *data == '\x2d' ){
  237. ++data;
  238. is_minus = true;
  239. }
  240. unsigned char ch = (unsigned char)(*data++ - '0');
  241. if (ch <= 9) {
  242. n = n * 10 + ch;
  243. } else {
  244. break;
  245. }
  246. } while (true);
  247. double num;
  248. if( is_minus == false ){
  249. num = (double)n / (double)read_db.mag;
  250. }else{
  251. num = -(double)n / (double)read_db.mag;
  252. }
  253. IS_PRINT == true && printf("%ld", lround(num*read_db.mag));
  254. };
  255. func2(i); IS_PRINT == true && printf(" ");
  256. func2(i+1); IS_PRINT == true && printf(" ");
  257. func2(i+2); IS_PRINT == true && printf(" ");
  258. func2(i+3); IS_PRINT == true && printf("\n");
  259. return true;
  260. }
  261.  
  262. bool CCC::get_elem_y(unsigned int i){
  263. read_data();
  264. //係数掛けで数値取得
  265. // auto func2 = [&](double* num) {
  266. auto func2 = [&](unsigned int i) {
  267. uint64_t n = 0;
  268. bool is_minus = false;
  269. do {
  270. // 2d=マイナス記号(-)
  271. if( *data == '\x2d' ){
  272. ++data;
  273. is_minus = true;
  274. }
  275. unsigned char ch = (unsigned char)(*data++ - '0');
  276. if (ch <= 9) {
  277. n = n * 10 + ch;
  278. } else {
  279. break;
  280. }
  281. } while (true);
  282. double num;
  283. if( is_minus == false ){
  284. num = (double)n / (double)read_db.mag;
  285. }else{
  286. num = -(double)n / (double)read_db.mag;
  287. }
  288. IS_PRINT == true && printf("%ld", lround(num*read_db.mag));
  289. };
  290. func2(i); IS_PRINT == true && printf(" ");
  291. func2(i+1); IS_PRINT == true && printf("\n");
  292.  
  293. return true;
  294. }
  295.  
  296. bool CCC::read(char file_path[]){
  297. if((fp=fopen(file_path, "rb"))==NULL){
  298. printf("ファイルを開けません。%s",file_path);
  299. return 0;
  300. }
  301.  
  302. // テスト用。
  303. if( READ_MODE == 0 ){
  304. // freadだけだとどれくらいの速度?
  305. size_t size;
  306. do{
  307. if((size = fread( data, sizeof(data[0]), BUF_SIZE, fp)) == 0){
  308. break;
  309. }
  310. if( size != BUF_SIZE ) data[size] = '\x00';
  311. IS_PRINT == true && printf("%s", data);
  312. } while(size == BUF_SIZE);
  313. return true;
  314. }else if( READ_MODE == 1 ){
  315. // read_data()だけだとどれくらいの速度?
  316. while( true ){
  317. size_t size = read_data();
  318. IS_PRINT == true && printf("%s", data);
  319. for(; *++data != '\x00'; );
  320. if( feof( fp ) && *data == '\x00' ) { break; }
  321. }
  322. return true;
  323. }
  324.  
  325. // ファイルコピー
  326. while( true ){
  327. t_section_db section_db;
  328. p_current_section_db = &section_db;
  329. get_section_name();
  330. get_section_index();
  331. for(unsigned int i=0; i<p_current_section_db->text_line_count; ++i){
  332. get_text();
  333. }
  334. for(unsigned int i=0; i<p_current_section_db->num_1; ++i){
  335. t_elem_db elem_db;
  336. p_current_elem_db = &elem_db;
  337. get_elem_index();
  338. get_elem_qq();
  339. switch( p_current_elem_db->type ){
  340. case TYPE_x:
  341. // 要素数を最初に広げる
  342. p_current_elem_db->numbers.resize(p_current_elem_db->num_line_count*4);
  343. for(unsigned int i=0; i<p_current_elem_db->num_line_count; ++i){
  344. get_elem_x(i);
  345. }
  346. break;
  347. case TYPE_y:
  348. p_current_elem_db->numbers.resize(p_current_elem_db->num_line_count*2);
  349. for(unsigned int i=0; i<p_current_elem_db->num_line_count; ++i){
  350. get_elem_y(i);
  351. }
  352. break;
  353. default:
  354. printf("## ERROR 101 ##\n");
  355. printf("%s\n", data);
  356. exit(1);
  357. }
  358. }
  359. if( feof( fp ) && *data == '\x00' ) { break; }
  360. }
  361. fclose( fp );
  362. return 0;
  363. }
  364.  
  365. int main(void){
  366. char file_path[] = "./aaa_13gb";
  367.  
  368. CCC ccc;
  369. ccc.initialize();
  370. ccc.read(file_path);
  371.  
  372. return 0;
  373. }
Success #stdin #stdout 0s 4400KB
stdin
Standard input is empty
stdout
ファイルを開けません。./aaa_13gb