headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / media / MediaAddOn.cpp
blob1b0e08defadb1ee6ba5c6f6fd64cb70ecd577a8f
1 /*
2 * Copyright (c) 2002, 2003, 2008 Marcus Overhagen <Marcus@Overhagen.de>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files or portions
6 * thereof (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so, subject
10 * to the following conditions:
12 * * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright notice
16 * in the binary, as well as this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided with
18 * the distribution.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
31 #include <MediaAddOn.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <new>
35 #include "debug.h"
36 #include "DataExchange.h"
39 #define MAX_FLAVOR_IN_FORMAT_COUNT 300
40 #define MAX_FLAVOR_OUT_FORMAT_COUNT 300
42 #define FLATTEN_MAGIC 'CODE'
43 #define FLATTEN_TYPECODE 'DFIT'
46 static char *
47 _newstrdup(const char *str)
49 if (str == NULL)
50 return NULL;
51 int len = strlen(str) + 1;
52 char *p = new(std::nothrow) char[len];
53 if (p)
54 memcpy(p, str, len);
55 return p;
59 // #pragma mark - dormant_node_info
62 dormant_node_info::dormant_node_info()
64 addon(-1),
65 flavor_id(-1)
67 name[0] = '\0';
71 dormant_node_info::~dormant_node_info()
76 // #pragma mark - flavor_info
79 /* DO NOT IMPLEMENT */
81 flavor_info &flavor_info::operator=(const flavor_info &other)
85 // #pragma mark - dormant_flavor_info
88 dormant_flavor_info::dormant_flavor_info()
90 name = NULL;
91 info = NULL;
92 kinds = 0;
93 flavor_flags = 0;
94 internal_id = 0;
95 possible_count = 0;
96 in_format_count = 0;
97 in_format_flags = 0;
98 in_formats = NULL;
99 out_format_count = 0;
100 out_format_flags = 0;
101 out_formats = NULL;
105 dormant_flavor_info::~dormant_flavor_info()
107 delete[] name;
108 delete[] info;
109 delete[] in_formats;
110 delete[] out_formats;
114 dormant_flavor_info::dormant_flavor_info(const dormant_flavor_info &clone)
116 name = NULL;
117 info = NULL;
118 in_formats = NULL;
119 out_formats = NULL;
121 *this = clone;
125 dormant_flavor_info &
126 dormant_flavor_info::operator=(const dormant_flavor_info &clone)
128 // call operator=(const flavor_info &clone) to copy the flavor_info base class
129 *this = static_cast<const flavor_info>(clone);
130 // copy the dormant_node_info member variable
131 node_info = clone.node_info;
132 return *this;
136 dormant_flavor_info &
137 dormant_flavor_info::operator=(const flavor_info &clone)
139 kinds = clone.kinds;
140 flavor_flags = clone.flavor_flags;
141 internal_id = clone.internal_id;
142 possible_count = clone.possible_count;
144 delete [] info;
145 info = _newstrdup(clone.info);
147 delete [] name;
148 name = _newstrdup(clone.name);
150 delete [] in_formats;
151 in_formats = NULL;
152 in_format_count = 0;
153 in_format_flags = clone.in_format_flags;
154 if ((kinds & B_BUFFER_CONSUMER) != 0) {
155 if (clone.in_format_count >= 0
156 && clone.in_format_count <= MAX_FLAVOR_IN_FORMAT_COUNT) {
157 in_formats = new(std::nothrow) media_format[clone.in_format_count];
158 if (in_formats != NULL && clone.in_formats != NULL) {
159 in_format_count = clone.in_format_count;
160 for (int i = 0; i < in_format_count; i++) {
161 const_cast<media_format &>(in_formats[i])
162 = clone.in_formats[i];
165 } else {
166 fprintf(stderr, "error: dormant_flavor_info::operator= clone.in_"
167 "format_count is invalid\n");
169 } else if (clone.in_format_count) {
170 fprintf(stderr, "warning: dormant_flavor_info::operator= not "
171 "B_BUFFER_CONSUMER and clone.in_format_count is != 0\n");
174 delete [] out_formats;
175 out_formats = NULL;
176 out_format_count = 0;
177 out_format_flags = clone.out_format_flags;
178 if (kinds & B_BUFFER_PRODUCER) {
179 if (clone.out_format_count >= 0
180 && clone.out_format_count <= MAX_FLAVOR_OUT_FORMAT_COUNT) {
181 out_formats = new(std::nothrow) media_format[clone.out_format_count];
182 if (out_formats != NULL && clone.out_formats != NULL) {
183 out_format_count = clone.out_format_count;
184 for (int i = 0; i < out_format_count; i++) {
185 const_cast<media_format &>(out_formats[i])
186 = clone.out_formats[i];
189 } else {
190 fprintf(stderr, "error dormant_flavor_info::operator= clone.out_"
191 "format_count is invalid\n");
193 } else if (clone.out_format_count) {
194 fprintf(stderr, "warning: dormant_flavor_info::operator= not "
195 "B_BUFFER_PRODUCER and clone.out_format_count is != 0\n");
198 // initialize node_info with default values
199 dormant_node_info defaultValues;
200 node_info = defaultValues;
202 return *this;
206 void
207 dormant_flavor_info::set_name(const char *newName)
209 delete[] name;
210 name = _newstrdup(newName);
214 void
215 dormant_flavor_info::set_info(const char *newInfo)
217 delete[] info;
218 info = _newstrdup(newInfo);
222 void
223 dormant_flavor_info::add_in_format(const media_format &in_format)
225 media_format *p = new(std::nothrow) media_format[in_format_count + 1];
226 if (p) {
227 for (int i = 0; i < in_format_count; i++)
228 p[i] = in_formats[i];
229 p[in_format_count] = in_format;
230 delete [] in_formats;
231 in_formats = p;
232 in_format_count += 1;
237 void
238 dormant_flavor_info::add_out_format(const media_format &out_format)
240 media_format *p = new(std::nothrow) media_format[out_format_count + 1];
241 if (p) {
242 for (int i = 0; i < out_format_count; i++)
243 p[i] = out_formats[i];
244 p[out_format_count] = out_format;
245 delete [] out_formats;
246 out_formats = p;
247 out_format_count += 1;
252 bool
253 dormant_flavor_info::IsFixedSize() const
255 return false;
259 type_code
260 dormant_flavor_info::TypeCode() const
262 return FLATTEN_TYPECODE;
266 ssize_t
267 dormant_flavor_info::FlattenedSize() const
269 ssize_t size = 0;
270 // magic
271 size += sizeof(int32);
272 // size
273 size += sizeof(int32);
274 // struct flavor_info
275 size += sizeof(int32) + strlen(name);
276 size += sizeof(int32) + strlen(info);
277 size += sizeof(kinds);
278 size += sizeof(flavor_flags);
279 size += sizeof(internal_id);
280 size += sizeof(possible_count);
281 size += sizeof(in_format_count);
282 size += sizeof(in_format_flags);
283 if (in_format_count > 0 && in_format_count <= MAX_FLAVOR_IN_FORMAT_COUNT
284 && in_formats != NULL)
285 size += in_format_count * sizeof(media_format);
286 size += sizeof(out_format_count);
287 size += sizeof(out_format_flags);
288 if (out_format_count > 0 && out_format_count <= MAX_FLAVOR_OUT_FORMAT_COUNT
289 && out_formats != NULL)
290 size += out_format_count * sizeof(media_format);
291 // struct dormant_node_info node_info
292 size += sizeof(node_info);
294 return size;
298 status_t
299 dormant_flavor_info::Flatten(void *buffer, ssize_t size) const
301 if (size < FlattenedSize())
302 return B_ERROR;
304 char *buf = (char *)buffer;
305 int32 nameLength = name ? (int32)strlen(name) : -1;
306 int32 infoLength = info ? (int32)strlen(info) : -1;
307 int32 inFormatCount = 0;
308 size_t inFormatSize = 0;
309 int32 outFormatCount = 0;
310 size_t outFormatSize = 0;
312 if ((kinds & B_BUFFER_CONSUMER) != 0 && in_format_count > 0
313 && in_formats != NULL) {
314 if (in_format_count <= MAX_FLAVOR_IN_FORMAT_COUNT) {
315 inFormatCount = in_format_count;
316 inFormatSize = in_format_count * sizeof(media_format);
317 } else {
318 fprintf(stderr, "error dormant_flavor_info::Flatten: "
319 "in_format_count is too large\n");
320 return B_ERROR;
324 if ((kinds & B_BUFFER_PRODUCER) != 0 && out_format_count > 0
325 && out_formats != NULL) {
326 if (out_format_count <= MAX_FLAVOR_OUT_FORMAT_COUNT) {
327 outFormatCount = out_format_count;
328 outFormatSize = out_format_count * sizeof(media_format);
329 } else {
330 fprintf(stderr, "error dormant_flavor_info::Flatten: "
331 "out_format_count is too large\n");
332 return B_ERROR;
336 // magic
337 *(int32*)buf = FLATTEN_MAGIC; buf += sizeof(int32);
339 // size
340 *(int32*)buf = FlattenedSize(); buf += sizeof(int32);
342 // struct flavor_info
343 *(int32*)buf = nameLength; buf += sizeof(int32);
344 if (nameLength > 0) {
345 memcpy(buf, name, nameLength);
346 buf += nameLength;
348 *(int32*)buf = infoLength; buf += sizeof(int32);
349 if (infoLength > 0) {
350 memcpy(buf, info, infoLength);
351 buf += infoLength;
354 *(uint64*)buf = kinds; buf += sizeof(uint64);
355 *(uint32*)buf = flavor_flags; buf += sizeof(uint32);
356 *(int32*)buf = internal_id; buf += sizeof(int32);
357 *(int32*)buf = possible_count; buf += sizeof(int32);
358 *(int32*)buf = inFormatCount; buf += sizeof(int32);
359 *(uint32*)buf = in_format_flags; buf += sizeof(uint32);
361 // XXX FIXME! we should not!!! make flat copies of media_format
362 memcpy(buf, in_formats, inFormatSize); buf += inFormatSize;
364 *(int32*)buf = outFormatCount; buf += sizeof(int32);
365 *(uint32*)buf = out_format_flags; buf += sizeof(uint32);
367 // XXX FIXME! we should not!!! make flat copies of media_format
368 memcpy(buf, out_formats, outFormatSize); buf += outFormatSize;
370 *(dormant_node_info*)buf = node_info; buf += sizeof(dormant_node_info);
372 return B_OK;
376 status_t
377 dormant_flavor_info::Unflatten(type_code c, const void *buffer, ssize_t size)
379 if (c != FLATTEN_TYPECODE)
380 return B_ERROR;
381 if (size < 8)
382 return B_ERROR;
384 const char *buf = (const char *)buffer;
385 int32 nameLength;
386 int32 infoLength;
388 // check magic
389 if (*(int32*)buf != FLATTEN_MAGIC)
390 return B_ERROR;
391 buf += sizeof(int32);
393 // check size
394 if (*(uint32*)buf > (uint32)size)
395 return B_ERROR;
396 buf += sizeof(int32);
398 delete[] name;
399 name = NULL;
400 delete[] info;
401 info = NULL;
402 delete[] in_formats;
403 in_formats = NULL;
404 in_format_count = 0;
405 delete[] out_formats;
406 out_formats = NULL;
407 out_format_count = 0;
409 // struct flavor_info
410 nameLength = *(int32*)buf; buf += sizeof(int32);
411 if (nameLength >= 0) { // if nameLength is -1, we leave name = 0
412 name = new(std::nothrow) char [nameLength + 1];
413 if (name) {
414 memcpy(name, buf, nameLength);
415 name[nameLength] = 0;
416 buf += nameLength; // XXX not save
420 infoLength = *(int32*)buf; buf += sizeof(int32);
421 if (infoLength >= 0) { // if infoLength is -1, we leave info = 0
422 info = new(std::nothrow) char [infoLength + 1];
423 if (info) {
424 memcpy(info, buf, infoLength);
425 info[infoLength] = 0;
426 buf += infoLength; // XXX not save
430 int32 count;
432 kinds = *(uint64*)buf; buf += sizeof(uint64);
433 flavor_flags = *(uint32*)buf; buf += sizeof(uint32);
434 internal_id = *(int32*)buf; buf += sizeof(int32);
435 possible_count = *(int32*)buf; buf += sizeof(int32);
436 count = *(int32*)buf; buf += sizeof(int32);
437 in_format_flags = *(uint32*)buf; buf += sizeof(uint32);
439 if (count > 0) {
440 if (count <= MAX_FLAVOR_IN_FORMAT_COUNT) {
441 in_formats = new(std::nothrow) media_format[count];
442 if (!in_formats)
443 return B_NO_MEMORY;
444 // TODO: we should not!!! make flat copies of media_format
445 memcpy(const_cast<media_format *>(in_formats), buf,
446 count * sizeof(media_format));
447 in_format_count = count;
449 buf += count * sizeof(media_format); // TODO: not save
452 count = *(int32*)buf; buf += sizeof(int32);
453 out_format_flags = *(uint32*)buf; buf += sizeof(uint32);
455 if (count > 0) {
456 if (count <= MAX_FLAVOR_OUT_FORMAT_COUNT) {
457 out_formats = new(std::nothrow) media_format[count];
458 if (!out_formats)
459 return B_NO_MEMORY;
460 // TODO: we should not!!! make flat copies of media_format
461 memcpy(const_cast<media_format *>(out_formats), buf,
462 count * sizeof(media_format));
463 out_format_count = count;
465 buf += count * sizeof(media_format); // TODO: not save
468 node_info = *(dormant_node_info*)buf; buf += sizeof(dormant_node_info);
470 return B_OK;
474 // #pragma mark - BMediaAddOn
477 BMediaAddOn::BMediaAddOn(image_id image)
479 fImage(image),
480 fAddon(0)
482 CALLED();
486 BMediaAddOn::~BMediaAddOn()
488 CALLED();
492 status_t
493 BMediaAddOn::InitCheck(const char **_failureText)
495 CALLED();
496 // only to be implemented by derived classes
497 *_failureText = "no error";
498 return B_OK;
502 int32
503 BMediaAddOn::CountFlavors()
505 CALLED();
506 // only to be implemented by derived classes
507 return 0;
511 status_t
512 BMediaAddOn::GetFlavorAt(int32 n, const flavor_info **_info)
514 CALLED();
515 // only to be implemented by derived classes
516 return B_ERROR;
520 BMediaNode*
521 BMediaAddOn::InstantiateNodeFor(const flavor_info *info, BMessage *config,
522 status_t *_error)
524 CALLED();
525 // only to be implemented by derived classes
526 return NULL;
530 status_t
531 BMediaAddOn::GetConfigurationFor(BMediaNode *node, BMessage *toMessage)
533 CALLED();
534 // only to be implemented by derived classes
535 return B_ERROR;
539 bool
540 BMediaAddOn::WantsAutoStart()
542 CALLED();
543 // only to be implemented by derived classes
544 return false;
548 status_t
549 BMediaAddOn::AutoStart(int count, BMediaNode **_node, int32 *_internalID,
550 bool *_hasMore)
552 CALLED();
553 // only to be implemented by derived classes
554 return B_ERROR;
558 status_t
559 BMediaAddOn::SniffRef(const entry_ref &file, BMimeType *mimeType,
560 float *_quality, int32 *_internalID)
562 CALLED();
563 // only to be implemented by BFileInterface derived classes
564 return B_ERROR;
568 status_t
569 BMediaAddOn::SniffType(const BMimeType &type, float *_quality,
570 int32 *_internalID)
572 CALLED();
573 // only to be implemented by BFileInterface derived classes
574 return B_ERROR;
578 status_t
579 BMediaAddOn::GetFileFormatList(int32 flavorID,
580 media_file_format *writableFormats, int32 maxWriteItems, int32 *_writeItems,
581 media_file_format *readableFormats, int32 maxReadItems, int32 *_readItems,
582 void *_reserved)
584 CALLED();
585 // only to be implemented by BFileInterface derived classes
586 return B_ERROR;
590 status_t
591 BMediaAddOn::SniffTypeKind(const BMimeType &type, uint64 kinds, float *_quality,
592 int32 *_internalID, void *_reserved)
594 CALLED();
595 // only to be implemented by BFileInterface derived classes
596 return B_ERROR;
600 image_id
601 BMediaAddOn::ImageID()
603 return fImage;
607 media_addon_id
608 BMediaAddOn::AddonID()
610 return fAddon;
614 // #pragma mark - protected BMediaAddOn
617 status_t
618 BMediaAddOn::NotifyFlavorChange()
620 CALLED();
621 if (fAddon == 0)
622 return B_ERROR;
624 add_on_server_rescan_flavors_command command;
625 command.add_on_id = fAddon;
626 return SendToAddOnServer(ADD_ON_SERVER_RESCAN_ADD_ON_FLAVORS, &command,
627 sizeof(command));
631 // #pragma mark - private BMediaAddOn
635 unimplemented:
636 BMediaAddOn::BMediaAddOn()
637 BMediaAddOn::BMediaAddOn(const BMediaAddOn &clone)
638 BMediaAddOn & BMediaAddOn::operator=(const BMediaAddOn &clone)
642 extern "C" {
643 // declared here to remove them from the class header file
644 status_t _Reserved_MediaAddOn_0__11BMediaAddOnPv(void *, void *); /* now used for BMediaAddOn::GetFileFormatList */
645 status_t _Reserved_MediaAddOn_1__11BMediaAddOnPv(void *, void *); /* now used for BMediaAddOn::SniffTypeKind */
646 status_t _Reserved_MediaAddOn_0__11BMediaAddOnPv(void *, void *) { return B_ERROR; }
647 status_t _Reserved_MediaAddOn_1__11BMediaAddOnPv(void *, void *) { return B_ERROR; }
650 status_t BMediaAddOn::_Reserved_MediaAddOn_2(void *) { return B_ERROR; }
651 status_t BMediaAddOn::_Reserved_MediaAddOn_3(void *) { return B_ERROR; }
652 status_t BMediaAddOn::_Reserved_MediaAddOn_4(void *) { return B_ERROR; }
653 status_t BMediaAddOn::_Reserved_MediaAddOn_5(void *) { return B_ERROR; }
654 status_t BMediaAddOn::_Reserved_MediaAddOn_6(void *) { return B_ERROR; }
655 status_t BMediaAddOn::_Reserved_MediaAddOn_7(void *) { return B_ERROR; }