1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include "plugin_db.h"
22 
23 #define TAG "plugin_db"
24 
25 #define _MAX_MIME_TYPES      32
26 #define _MAX_PRINT_FORMATS    8
27 #define _MAX_PLUGINS         16
28 
29 typedef struct {
30     wprint_plugin_t *plugin;
31     const char *name;
32     char mime_types[_MAX_MIME_TYPES][MAX_MIME_LENGTH + 1];
33     char print_formats[_MAX_PRINT_FORMATS][MAX_MIME_LENGTH + 1];
34     int version;
35     wprint_priority_t priority;
36 } _plugin_db_t;
37 
38 static _plugin_db_t _plugin[_MAX_PLUGINS];
39 static int _index = 0;
40 
plugin_reset()41 void plugin_reset() {
42     _index = 0;
43 }
44 
plugin_add(wprint_plugin_t * plugin)45 int plugin_add(wprint_plugin_t *plugin) {
46     char const **mt, **pf;
47     int i, j, index;
48 
49     if (plugin == NULL) {
50         return ERROR;
51     }
52 
53     index = _index;
54     mt = plugin->get_mime_types();
55     pf = plugin->get_print_formats();
56 
57     if ((mt == NULL) || (pf == NULL)) {
58         return ERROR;
59     }
60 
61     memset(&_plugin[index], 0, sizeof(_plugin_db_t));
62     _plugin[index].version = plugin->version;
63     _plugin[index].plugin = plugin;
64     _plugin[index].priority = plugin->priority;
65 
66     LOGI("MIME types:");
67     // save a pointer to the name for comparison
68 
69     i = j = 0;
70     while (mt[i]) {
71         if (strlen(mt[i]) < MAX_MIME_LENGTH) {
72             LOGI(" %s", mt[i]);
73             strncpy(_plugin[index].mime_types[j++], mt[i], MAX_MIME_LENGTH);
74         }
75         i++;
76     }
77     if (j < _MAX_MIME_TYPES) {
78         _plugin[index].mime_types[j][0] = 0;
79     }
80 
81     LOGI("print formats:");
82 
83     i = j = 0;
84     while (pf[i]) {
85         if (strlen(pf[i]) < MAX_MIME_LENGTH) {
86             LOGI(" %s", pf[i]);
87             strncpy(_plugin[index].print_formats[j++], pf[i], MAX_MIME_LENGTH);
88         }
89         i++;
90     }
91     if (j < _MAX_PRINT_FORMATS) {
92         _plugin[index].print_formats[j][0] = 0;
93     }
94 
95     _index++;
96 
97     return OK;
98 }
99 
plugin_search(const char * mt,const char * pf)100 wprint_plugin_t *plugin_search(const char *mt, const char *pf) {
101     int i, j, k;
102     _plugin_db_t *match = NULL;
103 
104     for (i = 0; i < _index; i++) {
105         j = 0;
106         while (strlen(_plugin[i].print_formats[j])) {
107             if (strcmp(_plugin[i].print_formats[j], pf) == 0) {
108                 k = 0;
109                 while (strlen(_plugin[i].mime_types[k])) {
110                     if (strcmp(_plugin[i].mime_types[k], mt) == 0) {
111                         bool use;
112                         use = ((match == NULL) || (_plugin[i].priority < match->priority));
113                         if (use) {
114                             match = &_plugin[i];
115                         }
116                     }
117                     k++;
118                 }
119             }
120             j++;
121         }
122     }
123     return ((match != NULL) ? match->plugin : NULL);
124 }
125 
plugin_get_mime_type_bit(const char * mime_type)126 unsigned long long plugin_get_mime_type_bit(const char *mime_type) {
127     unsigned long long bit = 0;
128     if (strcmp(MIME_TYPE_PDF, mime_type) == 0) {
129         bit = (unsigned long long) (1 << INPUT_MIME_TYPE_PDF);
130     } else if (strcmp(MIME_TYPE_PCLM, mime_type) == 0) {
131         bit = (unsigned long long) (1 << INPUT_MIME_TYPE_PCLM);
132     } else if (strcmp(MIME_TYPE_PWG, mime_type) == 0) {
133         bit = (unsigned long long) (1 << INPUT_MIME_TYPE_PWG);
134     }
135     return bit;
136 }
137 
plugin_get_passthru_input_formats(unsigned long long * input_formats)138 void plugin_get_passthru_input_formats(unsigned long long *input_formats) {
139     int i;
140     *input_formats = 0;
141     for (i = 0; i < _index; i++) {
142         // is this a passthrough plugin
143         if ((strcmp(_plugin[i].mime_types[0], _plugin[i].print_formats[0]) == 0) &&
144                 (strlen(_plugin[i].print_formats[1]) == 0)
145                 && (strlen(_plugin[i].mime_types[1]) == 0)) {
146             *input_formats |= plugin_get_mime_type_bit(_plugin[i].mime_types[0]);
147         }
148     }
149 }