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