OSDN Git Service

Fix Previous Bad commit for Cyanders Chapter Markers
[handbrake-jp/handbrake-jp-git.git] / test / parsecsv.c
1 /* $Id: parsecsv.c $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include <fcntl.h>
8 #include "hb.h"
9 #include "parsecsv.h"
10
11 /* Internal declarations */
12 #define is_newline(_x)      ( (_x) == 13 || \
13                               (_x) == 11 || \
14                               (_x) == 10 )
15                               
16 #define is_white(_x)        ( (_x) == '\t' || \
17                               (_x) == ' '  || \
18                               is_newline(_x) ) 
19                               
20 #define is_sep(_x)          ( (_x) == ',' )
21
22 #define is_esc(_x)          ( (_x) == '\\' )
23
24 #define CSV_CHAR_ERROR      0x8000
25 #define CSV_CHAR_EOF        0x4000
26 #define CSV_CHAR_ROWSEP     0x2000
27 #define CSV_CHAR_COLSEP     0x1000
28
29 #define CSV_PARSE_NORMAL    0x0000
30 #define CSV_PARSE_SEEK      0x0001
31 #define CSV_PARSE_ESC       0x0002
32
33 static uint16_t hb_parse_character( hb_csv_file_t * file );
34 static void hb_trim_end( char *text );
35
36 /* Open a CSV File */
37 hb_csv_file_t *hb_open_csv_file( const char *filepath )
38 {
39     hb_csv_file_t *file = NULL;
40     FILE * fileref;
41     
42     if( filepath == NULL )
43     {
44         return file;
45     }
46     
47     fileref = fopen( filepath, "r" );
48     if( fileref == NULL )
49     {
50         return file;
51     }
52     
53     file = malloc( sizeof( hb_csv_file_t ) );
54     file->fileref       = fileref;
55     file->eof           = 0;
56     file->parse_state   = CSV_PARSE_SEEK;
57     file->curr_col      = 0;
58     file->curr_row      = 0;
59     return file;
60 }
61
62 void hb_close_csv_file( hb_csv_file_t *file ) 
63 {
64     if( file == NULL )
65     {
66         return;
67     }
68     
69     fclose( file->fileref );
70     free( file );
71 }
72
73 /* Parse CSV Cells */
74 hb_csv_cell_t *hb_read_next_cell( hb_csv_file_t *file )
75 {
76     hb_csv_cell_t *cell = NULL;
77     uint16_t c;
78     int index;
79
80     if( file == NULL  )
81     {
82         return cell;
83     }
84     
85     if( file->eof )
86     {
87         return cell;
88     }
89     
90     cell = malloc( sizeof( hb_csv_cell_t ) );
91     cell->cell_row = file->curr_row;
92     cell->cell_col = file->curr_col;
93     index = 0;
94     while( CSV_CHAR_EOF != (c = hb_parse_character( file ) ) )
95     {
96         if( c == CSV_CHAR_ROWSEP )
97         {
98             file->curr_row++;
99             file->curr_col = 0;
100             break;
101         }
102         else if( c == CSV_CHAR_COLSEP )
103         {
104             file->curr_col++;
105             break;
106         }
107         else
108         {
109             if( index < 1023 )
110             {
111                 cell->cell_text[index] = (char)c;
112                 index++;
113             }
114         }
115     }
116     
117     if( c == CSV_CHAR_EOF )
118     {
119         file->eof = 1;
120     }
121     
122     /* Terminate the cell text */
123     cell->cell_text[index] = '\0';
124     hb_trim_end( cell->cell_text );
125     return cell;
126 }
127
128 void hb_dispose_cell( hb_csv_cell_t *cell )
129 {
130     if( cell == NULL )
131     {
132         return;
133     }
134     
135     free( cell );
136 }
137
138 /* Raw parsing */
139 static uint16_t hb_parse_character( hb_csv_file_t * file )
140 {
141     int byte;
142     uint16_t c;
143     int read_result;
144     int need_char = 1;
145     
146     if( file == NULL )
147     {
148         return CSV_CHAR_ERROR;
149     }
150     
151     while( need_char )
152     {
153         byte = fgetc( file->fileref );
154         if( feof( file->fileref ) )
155         {
156             return CSV_CHAR_EOF;
157         }
158         if( ferror( file->fileref ) )
159         {
160             return CSV_CHAR_ERROR;
161         }
162         
163         if( file->parse_state == CSV_PARSE_SEEK && is_white(byte) )
164         {
165             continue;
166         }
167         else if( file->parse_state != CSV_PARSE_ESC && is_esc(byte) )
168         {
169             file->parse_state = CSV_PARSE_ESC;
170             continue;
171         }
172         else if( file->parse_state != CSV_PARSE_ESC && is_sep(byte) )
173         {
174             file->parse_state = CSV_PARSE_SEEK;
175             need_char = 0;
176             c = CSV_CHAR_COLSEP;
177         }
178         else if( file->parse_state == CSV_PARSE_ESC )
179         {
180             file->parse_state = CSV_PARSE_NORMAL;
181             need_char = 0;
182             c = (uint16_t)byte;
183         }
184         else if( is_newline(byte) )
185         {
186             file->parse_state = CSV_PARSE_SEEK;
187             need_char = 0;
188             c = CSV_CHAR_ROWSEP;
189         }
190         else
191         {
192             file->parse_state = CSV_PARSE_NORMAL;
193             need_char = 0;
194             c = (uint16_t)byte;
195         }
196     }
197     
198     return c;
199 }
200
201 static void hb_trim_end( char *text )
202 {
203     if( text == NULL )
204     {
205         return;
206     }
207
208     int i = strlen(text) - 1;
209     
210     for( i = strlen(text) - 1; i >= 0 && is_white(text[i]) ; i-- )
211     {
212         text[i] = '\0';
213     }
214 }