diff options
Diffstat (limited to 'src/plugins/template_extractor.c')
-rw-r--r-- | src/plugins/template_extractor.c | 122 |
1 files changed, 107 insertions, 15 deletions
diff --git a/src/plugins/template_extractor.c b/src/plugins/template_extractor.c index 63f0393..b6f3371 100644 --- a/src/plugins/template_extractor.c +++ b/src/plugins/template_extractor.c | |||
@@ -21,21 +21,113 @@ | |||
21 | #include "platform.h" | 21 | #include "platform.h" |
22 | #include "extractor.h" | 22 | #include "extractor.h" |
23 | 23 | ||
24 | int | 24 | #include "extractor_plugins.h" |
25 | EXTRACTOR_template_extract (const unsigned char *data, | 25 | |
26 | size_t size, | 26 | struct template_state |
27 | EXTRACTOR_MetaDataProcessor proc, | 27 | { |
28 | void *proc_cls, | 28 | int state; |
29 | const char *options) | 29 | |
30 | /* more state fields here | ||
31 | * all variables that should survive more than one atomic read | ||
32 | * from the "file" are to be placed here. | ||
33 | */ | ||
34 | }; | ||
35 | |||
36 | enum TemplateState | ||
37 | { | ||
38 | TEMPLATE_INVALID = -1, | ||
39 | TEMPLATE_LOOKING_FOR_FOO = 0, | ||
40 | TEMPLATE_READING_FOO, | ||
41 | TEMPLATE_READING_BAR, | ||
42 | TEMPLATE_SEEKING_TO_ZOOL | ||
43 | }; | ||
44 | |||
45 | void | ||
46 | EXTRACTOR_template_init_state_method (struct EXTRACTOR_PluginList *plugin) | ||
30 | { | 47 | { |
31 | if (0 != proc (proc_cls, | 48 | struct template_state *state; |
32 | "template", | 49 | state = plugin->state = malloc (sizeof (struct template_state)); |
33 | EXTRACTOR_METATYPE_RESERVED, | 50 | if (state == NULL) |
34 | EXTRACTOR_METAFORMAT_UTF8, | 51 | return; |
35 | "text/plain", | 52 | state->state = TEMPLATE_LOOKING_FOR_FOO; /* or whatever is the initial one */ |
36 | "foo", | 53 | /* initialize other fields to their "uninitialized" values or defaults */ |
37 | strlen ("foo")+1)) | 54 | } |
55 | |||
56 | void | ||
57 | EXTRACTOR_template_discard_state_method (struct EXTRACTOR_PluginList *plugin) | ||
58 | { | ||
59 | if (plugin->state != NULL) | ||
60 | { | ||
61 | /* free other state fields that are heap-allocated */ | ||
62 | free (plugin->state); | ||
63 | } | ||
64 | plugin->state = NULL; | ||
65 | } | ||
66 | |||
67 | int | ||
68 | EXTRACTOR_template_extract_method (struct EXTRACTOR_PluginList *plugin, | ||
69 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | ||
70 | { | ||
71 | int64_t file_position; | ||
72 | int64_t file_size; | ||
73 | size_t offset = 0; | ||
74 | size_t size; | ||
75 | unsigned char *data; | ||
76 | unsigned char *ff; | ||
77 | struct mp3_state *state; | ||
78 | |||
79 | /* temporary variables are declared here */ | ||
80 | |||
81 | if (plugin == NULL || plugin->state == NULL) | ||
38 | return 1; | 82 | return 1; |
39 | /* insert more here */ | 83 | |
40 | return 0; | 84 | /* for easier access (and conforms better with the old plugins var names) */ |
85 | state = plugin->state; | ||
86 | file_position = plugin->position; | ||
87 | file_size = plugin->fsize; | ||
88 | size = plugin->map_size; | ||
89 | data = plugin->shm_ptr; | ||
90 | |||
91 | /* sanity checks */ | ||
92 | if (plugin->seek_request < 0) | ||
93 | return 1; | ||
94 | if (file_position - plugin->seek_request > 0) | ||
95 | { | ||
96 | plugin->seek_request = -1; | ||
97 | return 1; | ||
98 | } | ||
99 | if (plugin->seek_request - file_position < size) | ||
100 | offset = plugin->seek_request - file_position; | ||
101 | |||
102 | while (1) | ||
103 | { | ||
104 | switch (state->state) | ||
105 | { | ||
106 | case TEMPLATE_INVALID: | ||
107 | plugin->seek_request = -1; | ||
108 | return 1; | ||
109 | case TEMPLATE_LOOKING_FOR_FOO: | ||
110 | /* Find FOO in data buffer. | ||
111 | * If found, set offset to its position and set state to TEMPLATE_READING_FOO | ||
112 | * If not found, set seek_request to file_position + offset and return 1 | ||
113 | * (but it's better to give up as early as possible, to avoid reading the whole | ||
114 | * file byte-by-byte). | ||
115 | */ | ||
116 | break; | ||
117 | case TEMPLATE_READING_FOO: | ||
118 | /* See if offset + sizeof(foo) < size, otherwise set seek_request to offset and return 1; | ||
119 | * If file_position is 0, and size is still to small, give up. | ||
120 | * Read FOO, maybe increase offset to reflect that (depends on the parser logic). | ||
121 | * Either process FOO right here, or jump to another state (see ebml plugin for an example of complex | ||
122 | * state-jumps). | ||
123 | * If FOO says you need to seek somewhere - set offset to seek_target - file_position and set the | ||
124 | * next state (next state will check that offset < size; all states that do reading should do that, | ||
125 | * and also check for EOF). | ||
126 | */ | ||
127 | /* ... */ | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | /* Should not reach this */ | ||
132 | return 1; | ||
41 | } | 133 | } |