1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2015 Brazil
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License version 2.1 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "grn_ctx.h"
20#include "grn_str.h"
21
22#include <stdio.h>
23#include <string.h>
24
25#ifdef WIN32
26# include <share.h>
27#endif /* WIN32 */
28
29struct _grn_file_reader {
30 FILE *file;
31 grn_bool file_need_close;
32};
33
34grn_file_reader *
35grn_file_reader_open(grn_ctx *ctx, const char *path)
36{
37 grn_file_reader *reader;
38 FILE *file;
39 grn_bool file_need_close;
40
41 GRN_API_ENTER;
42
43 if (!path) {
44 ERR(GRN_INVALID_ARGUMENT, "[file-reader][open] path must not NULL");
45 GRN_API_RETURN(NULL);
46 }
47
48 if (strcmp(path, "-") == 0) {
49 file = stdin;
50 file_need_close = GRN_FALSE;
51 } else {
52 file = grn_fopen(path, "r");
53 if (!file) {
54 SERR("[file-reader][open] failed to open path: <%s>", path);
55 GRN_API_RETURN(NULL);
56 }
57 file_need_close = GRN_TRUE;
58 }
59
60 reader = GRN_MALLOC(sizeof(grn_file_reader));
61 reader->file = file;
62 reader->file_need_close = file_need_close;
63
64 GRN_API_RETURN(reader);
65}
66
67void
68grn_file_reader_close(grn_ctx *ctx, grn_file_reader *reader)
69{
70 if (!reader) {
71 return;
72 }
73
74 if (reader->file_need_close) {
75 if (fclose(reader->file) != 0) {
76 GRN_LOG(ctx, GRN_LOG_ERROR,
77 "[file-reader][close] failed to close: <%s>",
78 grn_strerror(errno));
79 }
80 }
81
82 GRN_FREE(reader);
83}
84
85grn_rc
86grn_file_reader_read_line(grn_ctx *ctx,
87 grn_file_reader *reader,
88 grn_obj *buffer)
89{
90 grn_rc rc = GRN_END_OF_DATA;
91
92 for (;;) {
93 size_t len;
94
95#define BUFFER_SIZE 4096
96 grn_bulk_reserve(ctx, buffer, BUFFER_SIZE);
97 if (!fgets(GRN_BULK_CURR(buffer), BUFFER_SIZE, reader->file)) {
98 break;
99 }
100#undef BUFFER_SIZE
101
102 if (!(len = strlen(GRN_BULK_CURR(buffer)))) { break; }
103 GRN_BULK_INCR_LEN(buffer, len);
104 rc = GRN_SUCCESS;
105 if (GRN_BULK_CURR(buffer)[-1] == '\n') { break; }
106 }
107
108 return rc;
109}
110