OSDN Git Service

import 0.9.3
[handbrake-jp/handbrake-jp.git] / test / parsecsv.c
1 /* $Id: parsecsv.c $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
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 need_char = 1;
144
145     if( file == NULL )
146     {
147         return CSV_CHAR_ERROR;
148     }
149
150     while( need_char )
151     {
152         byte = fgetc( file->fileref );
153         if( feof( file->fileref ) )
154         {
155             return CSV_CHAR_EOF;
156         }
157         if( ferror( file->fileref ) )
158         {
159             return CSV_CHAR_ERROR;
160         }
161
162         if( file->parse_state == CSV_PARSE_SEEK && is_white(byte) )
163         {
164             continue;
165         }
166         else if( file->parse_state != CSV_PARSE_ESC && is_esc(byte) )
167         {
168             file->parse_state = CSV_PARSE_ESC;
169             continue;
170         }
171         else if( file->parse_state != CSV_PARSE_ESC && is_sep(byte) )
172         {
173             file->parse_state = CSV_PARSE_SEEK;
174             need_char = 0;
175             c = CSV_CHAR_COLSEP;
176         }
177         else if( file->parse_state == CSV_PARSE_ESC )
178         {
179             file->parse_state = CSV_PARSE_NORMAL;
180             need_char = 0;
181             c = (uint16_t)byte;
182         }
183         else if( is_newline(byte) )
184         {
185             file->parse_state = CSV_PARSE_SEEK;
186             need_char = 0;
187             c = CSV_CHAR_ROWSEP;
188         }
189         else
190         {
191             file->parse_state = CSV_PARSE_NORMAL;
192             need_char = 0;
193             c = (uint16_t)byte;
194         }
195     }
196
197     return c;
198 }
199
200 static void hb_trim_end( char *text )
201 {
202     if( text == NULL )
203     {
204         return;
205     }
206
207     int i = strlen(text) - 1;
208
209     for( i = strlen(text) - 1; i >= 0 && is_white(text[i]) ; i-- )
210     {
211         text[i] = '\0';
212     }
213 }