1 /* This file is part of GNU Dico.
2    Copyright (C) 1998-2020 Sergey Poznyakoff
3 
4    GNU Dico is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    GNU Dico 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
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Dico.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #include <dicod.h>
18 
19 enum {
20     DBRF_NONE = 0,
21     DBRF_RCOUNT = 0x01,
22     DBRF_CCOUNT = 0x02
23 };
24 
25 dicod_db_result_t *
dicod_db_result_alloc(dicod_database_t * db,dico_result_t res)26 dicod_db_result_alloc(dicod_database_t *db, dico_result_t res)
27 {
28     dicod_db_result_t *dbr;
29     if (!res)
30 	return NULL;
31     dbr = xmalloc(sizeof(*dbr));
32     dbr->flags = DBRF_NONE;
33     dbr->db = db;
34     dbr->res = res;
35     return dbr;
36 }
37 
38 static inline struct dico_database_module *
dicod_db_result_module(dicod_db_result_t * dbr)39 dicod_db_result_module(dicod_db_result_t *dbr)
40 {
41     return dbr->db->instance->module;
42 }
43 
44 void
dicod_db_result_free(dicod_db_result_t * dbr)45 dicod_db_result_free(dicod_db_result_t *dbr)
46 {
47     dicod_db_result_module(dbr)->dico_free_result(dbr->res);
48     free(dbr);
49 }
50 
51 size_t
dicod_db_result_count(dicod_db_result_t * dbr)52 dicod_db_result_count(dicod_db_result_t *dbr)
53 {
54     if (!(dbr->flags & DBRF_RCOUNT)) {
55 	dbr->rcount = dicod_db_result_module(dbr)->dico_result_count(dbr->res);
56 	dbr->flags |= DBRF_RCOUNT;
57     }
58     return dbr->rcount;
59 }
60 
61 size_t
dicod_db_result_compare_count(dicod_db_result_t * dbr)62 dicod_db_result_compare_count(dicod_db_result_t *dbr)
63 {
64     if (!(dbr->flags & DBRF_CCOUNT)) {
65 	dbr->ccount = dicod_db_result_module(dbr)->dico_compare_count(dbr->res);
66 	dbr->flags |= DBRF_CCOUNT;
67     }
68     return dbr->ccount;
69 }
70 
71 int
dicod_db_result_output(dicod_db_result_t * dbr,size_t n,dico_stream_t str)72 dicod_db_result_output(dicod_db_result_t *dbr, size_t n, dico_stream_t str)
73 {
74     return dicod_db_result_module(dbr)->dico_output_result(dbr->res, n, str);
75 }
76 
77 dico_assoc_list_t
dicod_db_result_mime_header(dicod_db_result_t * dbr,size_t n)78 dicod_db_result_mime_header(dicod_db_result_t *dbr, size_t n)
79 {
80     dico_assoc_list_t hdr = NULL;
81     struct dico_database_module *mod = dicod_db_result_module(dbr);
82     dicod_database_t *db = dicod_db_result_db(dbr, n, result_db_all);
83 
84     if (db->mime_headers)
85 	hdr = dico_assoc_dup(db->mime_headers);
86     else
87 	dico_header_parse(&hdr, NULL);
88 
89     if (mod->dico_result_headers) {
90 	dico_assoc_list_t tmp = dico_assoc_dup(hdr);
91 	if (mod->dico_result_headers(dbr->res, tmp) == 0) {
92 	    dico_assoc_destroy(&hdr);
93 	    hdr = tmp;
94 	} else {
95 	    dico_assoc_destroy(&tmp);
96 	}
97     }
98 
99     return hdr;
100 }
101 
102 dicod_database_t *
dicod_db_result_db(dicod_db_result_t * dbr,size_t n,int flag)103 dicod_db_result_db(dicod_db_result_t *dbr, size_t n, int flag)
104 {
105     dicod_database_t *db = NULL;
106     struct dico_database_module *mod = dicod_db_result_module(dbr);
107     if (mod->dico_result_db) {
108 	db = mod->dico_result_db(dbr->res, n);
109 	if (db && flag == result_db_visible && !database_is_visible(db))
110 	    db = dbr->db;
111     }
112     return db ? db : dbr->db;
113 }
114 
115 
116 
117 
118