xref: /haiku/src/kits/media/MediaAddOn.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: MediaAddOn.cpp
4  *  DESCR:
5  ***********************************************************************/
6 #include <MediaAddOn.h>
7 #include <string.h>
8 #include <malloc.h>
9 #include "debug.h"
10 #include "DataExchange.h"
11 
12 /*
13  * some little helper function
14  */
15 
16 static inline char *newstrdup(const char *str);
17 char *newstrdup(const char *str)
18 {
19 	if (str == NULL)
20 		return NULL;
21 	int len = strlen(str) + 1;
22 	char *p = new char[len];
23 	memcpy(p,str,len);
24 	return p;
25 }
26 
27 #define FLATTEN_MAGIC 		'CODE'
28 #define FLATTEN_TYPECODE	'DFIT'
29 
30 /*************************************************************
31  * public dormant_node_info
32  *************************************************************/
33 
34 // final & verified
35 dormant_node_info::dormant_node_info()
36 	: addon(-1),
37 	flavor_id(-1)
38 {
39 	name[0] = '\0';
40 }
41 
42 // final
43 dormant_node_info::~dormant_node_info()
44 {
45 }
46 
47 /*************************************************************
48  * private flavor_info
49  *************************************************************/
50 
51 /* DO NOT IMPLEMENT */
52 /*
53 flavor_info &flavor_info::operator=(const flavor_info &other)
54 */
55 
56 /*************************************************************
57  * public dormant_flavor_info
58  *************************************************************/
59 
60 // final & verified
61 dormant_flavor_info::dormant_flavor_info()
62 {
63 	name = 0;
64 	info = 0;
65 	kinds = 0;
66 	flavor_flags = 0;
67 	internal_id = 0;
68 	possible_count = 0;
69 	in_format_count = 0;
70 	in_format_flags = 0;
71 	in_formats = 0;
72 	out_format_count = 0;
73 	out_format_flags = 0;
74 	out_formats = 0;
75 }
76 
77 
78 /* virtual */
79 dormant_flavor_info::~dormant_flavor_info()
80 {
81 	delete [] name;
82 	delete [] info;
83 	delete [] in_formats;
84 	delete [] out_formats;
85 }
86 
87 
88 dormant_flavor_info::dormant_flavor_info(const dormant_flavor_info &clone)
89 {
90 	*this = clone;
91 }
92 
93 
94 dormant_flavor_info &
95 dormant_flavor_info::operator=(const dormant_flavor_info &clone)
96 {
97 	// call operator=(const flavor_info &clone) to copy the flavor_info base class
98 	*this = static_cast<const flavor_info>(clone);
99 	// copy the dormant_node_info member variable
100 	node_info = clone.node_info;
101 	return *this;
102 }
103 
104 
105 dormant_flavor_info &
106 dormant_flavor_info::operator=(const flavor_info &clone)
107 {
108 	delete [] name;
109 	delete [] info;
110 	delete [] in_formats;
111 	delete [] out_formats;
112 
113 	name = newstrdup(clone.name);
114 	info = newstrdup(clone.info);
115 
116 	kinds = clone.kinds;
117 	flavor_flags = clone.flavor_flags;
118 	internal_id = clone.internal_id;
119 	possible_count = clone.possible_count;
120 
121 	in_format_count = clone.in_format_count;
122 	in_format_flags = clone.in_format_flags;
123 	out_format_count = clone.out_format_count;
124 	out_format_flags = clone.out_format_flags;
125 
126 	if (in_format_count > 0) {
127 		media_format *temp;
128 		temp = new media_format[in_format_count];
129 		for (int i = 0; i < in_format_count; i++)
130 			temp[i] = clone.in_formats[i];
131 		in_formats = temp;
132 	} else {
133 		in_formats = 0;
134 	}
135 
136 	if (out_format_count > 0) {
137 		media_format *temp;
138 		temp = new media_format[out_format_count];
139 		for (int i = 0; i < out_format_count; i++)
140 			temp[i] = clone.out_formats[i];
141 		out_formats = temp;
142 	} else {
143 		out_formats = 0;
144 	}
145 
146 	// initialize node_info with default values from dormant_node_info constructor
147 	dormant_node_info temp;
148 	node_info = temp;
149 
150 	return *this;
151 }
152 
153 
154 void
155 dormant_flavor_info::set_name(const char *in_name)
156 {
157 	delete [] name;
158 	name = newstrdup(in_name);
159 }
160 
161 
162 void
163 dormant_flavor_info::set_info(const char *in_info)
164 {
165 	delete [] info;
166 	info = newstrdup(in_info);
167 }
168 
169 
170 void
171 dormant_flavor_info::add_in_format(const media_format &in_format)
172 {
173 	media_format *temp;
174 	temp = new media_format[in_format_count + 1];
175 	for (int i = 0; i < in_format_count; i++)
176 		temp[i] = in_formats[i];
177 	temp[in_format_count] = in_format;
178 	delete [] in_formats;
179 	in_format_count += 1;
180 	in_formats = temp;
181 }
182 
183 
184 void
185 dormant_flavor_info::add_out_format(const media_format &out_format)
186 {
187 	media_format *temp;
188 	temp = new media_format[out_format_count + 1];
189 	for (int i = 0; i < out_format_count; i++)
190 		temp[i] = out_formats[i];
191 	temp[out_format_count] = out_format;
192 	delete [] out_formats;
193 	out_format_count += 1;
194 	out_formats = temp;
195 }
196 
197 
198 /* virtual */ bool
199 dormant_flavor_info::IsFixedSize() const
200 {
201 	return false;
202 }
203 
204 
205 /* virtual */ type_code
206 dormant_flavor_info::TypeCode() const
207 {
208 	return FLATTEN_TYPECODE;
209 }
210 
211 
212 /* virtual */ ssize_t
213 dormant_flavor_info::FlattenedSize() const
214 {
215 	ssize_t size = 0;
216 	// magic
217 	size += sizeof(int32);
218 	// size
219 	size += sizeof(int32);
220 	// struct flavor_info
221 	size += sizeof(int32) + strlen(name);
222 	size += sizeof(int32) + strlen(info);
223 	size += sizeof(kinds);
224 	size += sizeof(flavor_flags);
225 	size += sizeof(internal_id);
226 	size += sizeof(possible_count);
227 	size += sizeof(in_format_count);
228 	size += sizeof(in_format_flags);
229 	size += in_format_count * sizeof(media_format);
230 	size += sizeof(out_format_count);
231 	size += sizeof(out_format_flags);
232 	size += out_format_count * sizeof(media_format);
233 	// struct dormant_node_info	node_info
234 	size += sizeof(node_info);
235 
236 	return size;
237 }
238 
239 
240 /* virtual */ status_t
241 dormant_flavor_info::Flatten(void *buffer,
242 							 ssize_t size) const
243 {
244 	if (size < FlattenedSize())
245 		return B_ERROR;
246 
247 	char *buf = (char *)buffer;
248 	int32 namelen = name ? (int32)strlen(name) : -1;
249 	int32 infolen = info ? (int32)strlen(info) : -1;
250 
251 	// magic
252 	*(int32*)buf = FLATTEN_MAGIC; buf += sizeof(int32);
253 
254 	// size
255 	*(int32*)buf = FlattenedSize(); buf += sizeof(int32);
256 
257 	// struct flavor_info
258 	*(int32*)buf = namelen; buf += sizeof(int32);
259 	if (namelen > 0) {
260 		memcpy(buf,name,namelen);
261 		buf += namelen;
262 	}
263 	*(int32*)buf = infolen; buf += sizeof(int32);
264 	if (infolen > 0) {
265 		memcpy(buf,info,infolen);
266 		buf += infolen;
267 	}
268 
269 	*(uint64*)buf = kinds; buf += sizeof(uint64);
270 	*(uint32*)buf = flavor_flags; buf += sizeof(uint32);
271 	*(int32*)buf = internal_id; buf += sizeof(int32);
272 	*(int32*)buf = possible_count; buf += sizeof(int32);
273 	*(int32*)buf = in_format_count; buf += sizeof(int32);
274 	*(uint32*)buf = in_format_flags; buf += sizeof(uint32);
275 
276 	// XXX FIXME! we should not!!! make flat copies	of media_format
277 	memcpy(buf,in_formats,in_format_count * sizeof(media_format)); buf += in_format_count * sizeof(media_format);
278 
279 	*(int32*)buf = out_format_count; buf += sizeof(int32);
280 	*(uint32*)buf = out_format_flags; buf += sizeof(uint32);
281 
282 	// XXX FIXME! we should not!!! make flat copies	of media_format
283 	memcpy(buf,out_formats,out_format_count * sizeof(media_format)); buf += out_format_count * sizeof(media_format);
284 
285 	*(dormant_node_info*)buf = node_info; buf += sizeof(dormant_node_info);
286 
287 	return B_OK;
288 }
289 
290 
291 /* virtual */ status_t
292 dormant_flavor_info::Unflatten(type_code c,
293 							   const void *buffer,
294 							   ssize_t size)
295 {
296 	if (c != FLATTEN_TYPECODE)
297 		return B_ERROR;
298 	if (size < 8)
299 		return B_ERROR;
300 
301 	const char *buf = (const char *)buffer;
302 	int32 namelen;
303 	int32 infolen;
304 
305 	// magic
306 	if (*(int32*)buf != FLATTEN_MAGIC)
307 		return B_ERROR;
308 	buf += sizeof(int32);
309 
310 	// size
311 	if (*(int32*)buf > size)
312 		return B_ERROR;
313 	buf += sizeof(int32);
314 
315 
316 	delete [] name;
317 	delete [] info;
318 	delete [] in_formats;
319 	delete [] out_formats;
320 	name = 0;
321 	info = 0;
322 	in_formats = 0;
323 	out_formats = 0;
324 
325 
326 	// struct flavor_info
327 	namelen = *(int32*)buf; buf += sizeof(int32);
328 	if (namelen >= 0) { // if namelen is -1, we leave name = 0
329 		name = new char [namelen + 1];
330 		memcpy(name,buf,namelen);
331 		name[namelen] = 0;
332 		buf += namelen;
333 	}
334 
335 	infolen = *(int32*)buf; buf += sizeof(int32);
336 	if (infolen >= 0) { // if infolen is -1, we leave info = 0
337 		info = new char [infolen + 1];
338 		memcpy(info,buf,infolen);
339 		info[infolen] = 0;
340 		buf += infolen;
341 	}
342 
343 	kinds = *(uint64*)buf; buf += sizeof(uint64);
344 	flavor_flags = *(uint32*)buf; buf += sizeof(uint32);
345 	internal_id = *(int32*)buf; buf += sizeof(int32);
346 	possible_count = *(int32*)buf; buf += sizeof(int32);
347 	in_format_count = *(int32*)buf; buf += sizeof(int32);
348 	in_format_flags = *(uint32*)buf; buf += sizeof(uint32);
349 
350 	// XXX FIXME! we should not!!! make flat copies	of media_format
351 	if (in_format_count > 0) {
352 		in_formats = new media_format[in_format_count];
353 		memcpy((media_format *)in_formats,buf,in_format_count * sizeof(media_format));
354 		buf += in_format_count * sizeof(media_format);
355 	}
356 
357 	out_format_count = *(int32*)buf; buf += sizeof(int32);
358 	out_format_flags = *(uint32*)buf; buf += sizeof(uint32);
359 
360 	// XXX FIXME! we should not!!! make flat copies	of media_format
361 	if (out_format_count > 0) {
362 		out_formats = new media_format[out_format_count];
363 		memcpy((media_format *)out_formats,buf,out_format_count * sizeof(media_format));
364 		buf += out_format_count * sizeof(media_format);
365 	}
366 
367 	node_info = *(dormant_node_info*)buf; buf += sizeof(dormant_node_info);
368 
369 	return B_OK;
370 }
371 
372 /*************************************************************
373  * public BMediaAddOn
374  *************************************************************/
375 
376 /* explicit */
377 BMediaAddOn::BMediaAddOn(image_id image) :
378 	fImage(image),
379 	fAddon(0)
380 {
381 	CALLED();
382 }
383 
384 
385 /* virtual */
386 BMediaAddOn::~BMediaAddOn()
387 {
388 	CALLED();
389 }
390 
391 
392 /* virtual */ status_t
393 BMediaAddOn::InitCheck(const char **out_failure_text)
394 {
395 	CALLED();
396 	// only to be implemented by derived classes
397 	*out_failure_text = "no error";
398 	return B_OK;
399 }
400 
401 
402 /* virtual */ int32
403 BMediaAddOn::CountFlavors()
404 {
405 	CALLED();
406 	// only to be implemented by derived classes
407 	return 0;
408 }
409 
410 
411 /* virtual */ status_t
412 BMediaAddOn::GetFlavorAt(int32 n,
413 						 const flavor_info **out_info)
414 {
415 	CALLED();
416 	// only to be implemented by derived classes
417 	return B_ERROR;
418 }
419 
420 
421 /* virtual */ BMediaNode *
422 BMediaAddOn::InstantiateNodeFor(const flavor_info *info,
423 								BMessage *config,
424 								status_t *out_error)
425 {
426 	CALLED();
427 	// only to be implemented by derived classes
428 	return NULL;
429 }
430 
431 
432 /* virtual */ status_t
433 BMediaAddOn::GetConfigurationFor(BMediaNode *your_node,
434 								 BMessage *into_message)
435 {
436 	CALLED();
437 	// only to be implemented by derived classes
438 	return B_ERROR;
439 }
440 
441 
442 /* virtual */ bool
443 BMediaAddOn::WantsAutoStart()
444 {
445 	CALLED();
446 	// only to be implemented by derived classes
447 	return false;
448 }
449 
450 
451 /* virtual */ status_t
452 BMediaAddOn::AutoStart(int in_count,
453 					   BMediaNode **out_node,
454 					   int32 *out_internal_id,
455 					   bool *out_has_more)
456 {
457 	CALLED();
458 	// only to be implemented by derived classes
459 	return B_ERROR;
460 }
461 
462 
463 /* virtual */ status_t
464 BMediaAddOn::SniffRef(const entry_ref &file,
465 					  BMimeType *io_mime_type,
466 					  float *out_quality,
467 					  int32 *out_internal_id)
468 {
469 	CALLED();
470 	// only to be implemented by BFileInterface derived classes
471 	return B_ERROR;
472 }
473 
474 
475 /* virtual */ status_t
476 BMediaAddOn::SniffType(const BMimeType &type,
477 					   float *out_quality,
478 					   int32 *out_internal_id)
479 {
480 	CALLED();
481 	// only to be implemented by BFileInterface derived classes
482 	return B_ERROR;
483 }
484 
485 
486 /* virtual */ status_t
487 BMediaAddOn::GetFileFormatList(int32 flavor_id,
488 							   media_file_format *out_writable_formats,
489 							   int32 in_write_items,
490 							   int32 *out_write_items,
491 							   media_file_format *out_readable_formats,
492 							   int32 in_read_items,
493 							   int32 *out_read_items,
494 							   void *_reserved)
495 {
496 	CALLED();
497 	// only to be implemented by BFileInterface derived classes
498 	return B_ERROR;
499 }
500 
501 
502 /* virtual */ status_t
503 BMediaAddOn::SniffTypeKind(const BMimeType &type,
504 						   uint64 in_kinds,
505 						   float *out_quality,
506 						   int32 *out_internal_id,
507 						   void *_reserved)
508 {
509 	CALLED();
510 	// only to be implemented by BFileInterface derived classes
511 	return B_ERROR;
512 }
513 
514 
515 image_id
516 BMediaAddOn::ImageID()
517 {
518 	return fImage;
519 }
520 
521 
522 media_addon_id
523 BMediaAddOn::AddonID()
524 {
525 	return fAddon;
526 }
527 
528 /*************************************************************
529  * protected BMediaAddOn
530  *************************************************************/
531 
532 status_t
533 BMediaAddOn::NotifyFlavorChange()
534 {
535 	CALLED();
536 	if (fAddon == 0)
537 		return B_ERROR;
538 
539 	addonserver_rescan_mediaaddon_flavors_command command;
540 	command.addonid = fAddon;
541 	return SendToAddonServer(ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS, &command, sizeof(command));
542 }
543 
544 /*************************************************************
545  * private BMediaAddOn
546  *************************************************************/
547 
548 /*
549 unimplemented:
550 BMediaAddOn::BMediaAddOn()
551 BMediaAddOn::BMediaAddOn(const BMediaAddOn &clone)
552 BMediaAddOn & BMediaAddOn::operator=(const BMediaAddOn &clone)
553 */
554 
555 
556 /*************************************************************
557  * private BMediaAddOn
558  *************************************************************/
559 
560 extern "C" {
561 	// declared here to remove them from the class header file
562 	status_t _Reserved_MediaAddOn_0__11BMediaAddOnPv(void *, void *); /* now used for BMediaAddOn::GetFileFormatList */
563 	status_t _Reserved_MediaAddOn_1__11BMediaAddOnPv(void *, void *); /* now used for BMediaAddOn::SniffTypeKind */
564 	status_t _Reserved_MediaAddOn_0__11BMediaAddOnPv(void *, void *) { return B_ERROR; }
565 	status_t _Reserved_MediaAddOn_1__11BMediaAddOnPv(void *, void *) { return B_ERROR; }
566 };
567 
568 status_t BMediaAddOn::_Reserved_MediaAddOn_2(void *) { return B_ERROR; }
569 status_t BMediaAddOn::_Reserved_MediaAddOn_3(void *) { return B_ERROR; }
570 status_t BMediaAddOn::_Reserved_MediaAddOn_4(void *) { return B_ERROR; }
571 status_t BMediaAddOn::_Reserved_MediaAddOn_5(void *) { return B_ERROR; }
572 status_t BMediaAddOn::_Reserved_MediaAddOn_6(void *) { return B_ERROR; }
573 status_t BMediaAddOn::_Reserved_MediaAddOn_7(void *) { return B_ERROR; }
574 
575