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_impl.h" |
20 | |
21 | #ifdef GRN_WITH_MRUBY |
22 | #include <mruby.h> |
23 | #include <mruby/data.h> |
24 | #include <mruby/hash.h> |
25 | #include <mruby/string.h> |
26 | |
27 | #include "../grn_mrb.h" |
28 | #include "../grn_output.h" |
29 | #include "mrb_ctx.h" |
30 | #include "mrb_writer.h" |
31 | #include "mrb_options.h" |
32 | |
33 | static mrb_value |
34 | writer_write(mrb_state *mrb, mrb_value self) |
35 | { |
36 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
37 | mrb_value target; |
38 | |
39 | mrb_get_args(mrb, "o" , &target); |
40 | |
41 | switch (mrb_type(target)) { |
42 | case MRB_TT_FALSE : |
43 | if (mrb_nil_p(target)) { |
44 | GRN_OUTPUT_NULL(); |
45 | } else { |
46 | GRN_OUTPUT_BOOL(GRN_FALSE); |
47 | } |
48 | break; |
49 | case MRB_TT_TRUE : |
50 | GRN_OUTPUT_BOOL(GRN_TRUE); |
51 | break; |
52 | case MRB_TT_FIXNUM : |
53 | GRN_OUTPUT_INT32(mrb_fixnum(target)); |
54 | break; |
55 | case MRB_TT_FLOAT : |
56 | GRN_OUTPUT_FLOAT(mrb_float(target)); |
57 | break; |
58 | case MRB_TT_SYMBOL : |
59 | { |
60 | const char *name; |
61 | mrb_int name_length; |
62 | |
63 | name = mrb_sym2name_len(mrb, mrb_symbol(target), &name_length); |
64 | GRN_OUTPUT_STR(name, name_length); |
65 | } |
66 | break; |
67 | case MRB_TT_STRING : |
68 | GRN_OUTPUT_STR(RSTRING_PTR(target), RSTRING_LEN(target)); |
69 | break; |
70 | default : |
71 | mrb_raisef(mrb, E_ARGUMENT_ERROR, |
72 | "must be nil, true, false, number, float, symbol or string: " |
73 | "%S" , |
74 | target); |
75 | break; |
76 | } |
77 | |
78 | return mrb_nil_value(); |
79 | } |
80 | |
81 | static mrb_value |
82 | writer_open_array(mrb_state *mrb, mrb_value self) |
83 | { |
84 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
85 | char *name; |
86 | mrb_int n_elements; |
87 | |
88 | mrb_get_args(mrb, "zi" , &name, &n_elements); |
89 | GRN_OUTPUT_ARRAY_OPEN(name, n_elements); |
90 | |
91 | return mrb_nil_value(); |
92 | } |
93 | |
94 | static mrb_value |
95 | writer_close_array(mrb_state *mrb, mrb_value self) |
96 | { |
97 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
98 | |
99 | GRN_OUTPUT_ARRAY_CLOSE(); |
100 | |
101 | return mrb_nil_value(); |
102 | } |
103 | |
104 | static mrb_value |
105 | writer_open_map(mrb_state *mrb, mrb_value self) |
106 | { |
107 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
108 | char *name; |
109 | mrb_int n_elements; |
110 | |
111 | mrb_get_args(mrb, "zi" , &name, &n_elements); |
112 | GRN_OUTPUT_MAP_OPEN(name, n_elements); |
113 | |
114 | return mrb_nil_value(); |
115 | } |
116 | |
117 | static mrb_value |
118 | writer_close_map(mrb_state *mrb, mrb_value self) |
119 | { |
120 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
121 | |
122 | GRN_OUTPUT_MAP_CLOSE(); |
123 | |
124 | return mrb_nil_value(); |
125 | } |
126 | |
127 | static mrb_value |
128 | writer_write_table_columns(mrb_state *mrb, mrb_value self) |
129 | { |
130 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
131 | mrb_value mrb_table; |
132 | char *columns; |
133 | mrb_int columns_size; |
134 | grn_obj *table; |
135 | grn_obj_format format; |
136 | int n_hits = 0; |
137 | int offset = 0; |
138 | int limit = 0; |
139 | int hits_offset = 0; |
140 | |
141 | mrb_get_args(mrb, "os" , &mrb_table, &columns, &columns_size); |
142 | |
143 | table = DATA_PTR(mrb_table); |
144 | GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, hits_offset); |
145 | format.flags |= GRN_OBJ_FORMAT_WITH_COLUMN_NAMES; |
146 | { |
147 | grn_rc rc; |
148 | rc = grn_output_format_set_columns(ctx, &format, |
149 | table, columns, columns_size); |
150 | if (rc != GRN_SUCCESS) { |
151 | GRN_OBJ_FORMAT_FIN(ctx, &format); |
152 | grn_mrb_ctx_check(mrb); |
153 | } |
154 | } |
155 | GRN_OUTPUT_TABLE_COLUMNS(table, &format); |
156 | GRN_OBJ_FORMAT_FIN(ctx, &format); |
157 | |
158 | return mrb_nil_value(); |
159 | } |
160 | |
161 | static mrb_value |
162 | writer_write_table_records(mrb_state *mrb, mrb_value self) |
163 | { |
164 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
165 | mrb_value mrb_table; |
166 | mrb_value mrb_options = mrb_nil_value(); |
167 | char *columns; |
168 | mrb_int columns_size; |
169 | grn_obj *table; |
170 | grn_obj_format format; |
171 | int n_hits = 0; |
172 | int offset = 0; |
173 | int limit = -1; |
174 | int hits_offset = 0; |
175 | |
176 | mrb_get_args(mrb, "os|H" , &mrb_table, &columns, &columns_size, &mrb_options); |
177 | |
178 | table = DATA_PTR(mrb_table); |
179 | if (!mrb_nil_p(mrb_options)) { |
180 | mrb_value mrb_offset; |
181 | mrb_value mrb_limit; |
182 | |
183 | mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset" ); |
184 | if (!mrb_nil_p(mrb_offset)) { |
185 | offset = mrb_fixnum(mrb_offset); |
186 | } |
187 | |
188 | mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit" ); |
189 | if (!mrb_nil_p(mrb_limit)) { |
190 | limit = mrb_fixnum(mrb_limit); |
191 | } |
192 | } |
193 | if (limit < 0) { |
194 | limit = grn_table_size(ctx, table) + limit + 1; |
195 | } |
196 | GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, hits_offset); |
197 | { |
198 | grn_rc rc; |
199 | rc = grn_output_format_set_columns(ctx, &format, |
200 | table, columns, columns_size); |
201 | if (rc != GRN_SUCCESS) { |
202 | GRN_OBJ_FORMAT_FIN(ctx, &format); |
203 | grn_mrb_ctx_check(mrb); |
204 | } |
205 | } |
206 | GRN_OUTPUT_TABLE_RECORDS(table, &format); |
207 | GRN_OBJ_FORMAT_FIN(ctx, &format); |
208 | |
209 | return mrb_nil_value(); |
210 | } |
211 | |
212 | static mrb_value |
213 | writer_set_content_type(mrb_state *mrb, mrb_value self) |
214 | { |
215 | grn_ctx *ctx = (grn_ctx *)mrb->ud; |
216 | mrb_int content_type; |
217 | |
218 | mrb_get_args(mrb, "i" , &content_type); |
219 | |
220 | grn_ctx_set_output_type(ctx, content_type); |
221 | |
222 | return mrb_nil_value(); |
223 | } |
224 | |
225 | void |
226 | grn_mrb_writer_init(grn_ctx *ctx) |
227 | { |
228 | grn_mrb_data *data = &(ctx->impl->mrb); |
229 | mrb_state *mrb = data->state; |
230 | struct RClass *module = data->module; |
231 | struct RClass *klass; |
232 | |
233 | klass = mrb_define_class_under(mrb, module, "Writer" , mrb->object_class); |
234 | |
235 | mrb_define_method(mrb, klass, "write" , writer_write, MRB_ARGS_REQ(1)); |
236 | mrb_define_method(mrb, klass, "open_array" , |
237 | writer_open_array, MRB_ARGS_REQ(2)); |
238 | mrb_define_method(mrb, klass, "close_array" , |
239 | writer_close_array, MRB_ARGS_NONE()); |
240 | mrb_define_method(mrb, klass, "open_map" , |
241 | writer_open_map, MRB_ARGS_REQ(2)); |
242 | mrb_define_method(mrb, klass, "close_map" , |
243 | writer_close_map, MRB_ARGS_NONE()); |
244 | |
245 | mrb_define_method(mrb, klass, "write_table_columns" , |
246 | writer_write_table_columns, MRB_ARGS_REQ(2)); |
247 | mrb_define_method(mrb, klass, "write_table_records" , |
248 | writer_write_table_records, MRB_ARGS_ARG(2, 1)); |
249 | |
250 | mrb_define_method(mrb, klass, "content_type=" , |
251 | writer_set_content_type, MRB_ARGS_REQ(1)); |
252 | } |
253 | #endif |
254 | |