1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: PropertyInfo.h 23 // Author: Marc Flerackers (mflerackers@androme.be) 24 // Description: Utility class for maintain scripting information. 25 //------------------------------------------------------------------------------ 26 27 // Standard Includes ----------------------------------------------------------- 28 29 // System Includes ------------------------------------------------------------- 30 #include <PropertyInfo.h> 31 #include <Message.h> 32 #include <Errors.h> 33 #include <ByteOrder.h> 34 #include <DataIO.h> 35 #include <string.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 39 // Project Includes ------------------------------------------------------------ 40 41 // Local Includes -------------------------------------------------------------- 42 43 // Local Defines --------------------------------------------------------------- 44 45 // Globals --------------------------------------------------------------------- 46 47 //------------------------------------------------------------------------------ 48 BPropertyInfo::BPropertyInfo(property_info *p, value_info *ci, 49 bool free_on_delete) 50 : fPropInfo(p), 51 fValueInfo(ci), 52 fPropCount(0), 53 fInHeap(free_on_delete), 54 fValueCount(0) 55 { 56 if (fPropInfo) 57 { 58 while (fPropInfo[fPropCount].name) 59 fPropCount++; 60 } 61 62 if (fValueInfo) 63 { 64 while (fValueInfo[fValueCount].name) 65 fValueCount++; 66 } 67 } 68 //------------------------------------------------------------------------------ 69 BPropertyInfo::~BPropertyInfo() 70 { 71 FreeMem(); 72 } 73 //------------------------------------------------------------------------------ 74 int32 BPropertyInfo::FindMatch(BMessage *msg, int32 index, BMessage *spec, 75 int32 form, const char *prop, void *data) const 76 { 77 int32 property_index = 0; 78 79 while ((fPropInfo != NULL) && (fPropInfo[property_index].name)) { 80 property_info *propInfo = fPropInfo + property_index; 81 82 if ((strcmp(propInfo->name, prop) == 0) && 83 (FindCommand(msg->what, index, propInfo)) && 84 (FindSpecifier(form, propInfo))) { 85 if (data) 86 *((uint32*)data) = propInfo->extra_data; 87 return property_index; 88 } 89 property_index++; 90 } 91 92 return B_ERROR; 93 } 94 //------------------------------------------------------------------------------ 95 bool BPropertyInfo::IsFixedSize() const 96 { 97 return false; 98 } 99 //------------------------------------------------------------------------------ 100 type_code BPropertyInfo::TypeCode() const 101 { 102 return B_PROPERTY_INFO_TYPE; 103 } 104 //------------------------------------------------------------------------------ 105 ssize_t BPropertyInfo::FlattenedSize() const 106 { 107 size_t size = (2 * sizeof(int32)) + 1; 108 109 if (fPropInfo) 110 { 111 // Main chunks 112 for (int32 pi = 0; fPropInfo[pi].name != NULL; pi++) 113 { 114 size += strlen(fPropInfo[pi].name) + 1; 115 116 if (fPropInfo[pi].usage) 117 size += strlen(fPropInfo[pi].usage) + 1; 118 else 119 size += sizeof(char); 120 121 size += sizeof(int32); 122 123 for (int32 i = 0; i < 10 && fPropInfo[pi].commands[i] != 0; i++) 124 size += sizeof(int32); 125 size += sizeof(int32); 126 127 for (int32 i = 0; i < 10 && fPropInfo[pi].specifiers[i] != 0; i++) 128 size += sizeof(int32); 129 size += sizeof(int32); 130 } 131 132 // Type chunks 133 for (int32 pi = 0; fPropInfo[pi].name != NULL; pi++) 134 { 135 for (int32 i = 0; i < 10 && fPropInfo[pi].types[i] != 0; i++) 136 size += sizeof(int32); 137 size += sizeof(int32); 138 139 for (int32 i = 0; i < 3 && fPropInfo[pi].ctypes[i].pairs[0].name != 0; i++) 140 { 141 for (int32 j = 0; j < 5 && fPropInfo[pi].ctypes[i].pairs[j].name != 0; j++) 142 { 143 size += strlen(fPropInfo[pi].ctypes[i].pairs[j].name) + 1; 144 size += sizeof(int32); 145 } 146 size += sizeof(int32); 147 } 148 size += sizeof(int32); 149 } 150 } 151 152 if (fValueInfo) 153 { 154 size += sizeof(int16); 155 156 // Chunks 157 for (int32 vi = 0; fValueInfo[vi].name != NULL; vi++) 158 { 159 size += sizeof(int32); 160 size += sizeof(int32); 161 162 size += strlen(fValueInfo[vi].name) + 1; 163 164 if (fValueInfo[vi].usage) 165 size += strlen(fValueInfo[vi].usage) + 1; 166 else 167 size += sizeof(char); 168 169 size += sizeof(int32); 170 } 171 } 172 173 return size; 174 } 175 //------------------------------------------------------------------------------ 176 status_t BPropertyInfo::Flatten(void *buffer, ssize_t numBytes) const 177 { 178 if (numBytes < FlattenedSize()) 179 return B_NO_MEMORY; 180 181 if (buffer == NULL) 182 return B_BAD_VALUE; 183 184 BMemoryIO flatData(buffer, numBytes); 185 186 char tmpChar = B_HOST_IS_BENDIAN; 187 int32 tmpInt; 188 189 flatData.Write(&tmpChar, sizeof(tmpChar)); 190 flatData.Write(&fPropCount, sizeof(fPropCount)); 191 tmpInt = 0x01 | (fValueInfo ? 0x2 : 0x0); 192 flatData.Write(&tmpInt, sizeof(tmpInt)); 193 194 if (fPropInfo) { // Main chunks 195 for (int32 pi = 0; fPropInfo[pi].name != NULL; pi++) { 196 flatData.Write(fPropInfo[pi].name, strlen(fPropInfo[pi].name) + 1); 197 if (fPropInfo[pi].usage != NULL) { 198 flatData.Write(fPropInfo[pi].usage, strlen(fPropInfo[pi].usage) + 1); 199 } 200 else { 201 tmpChar = 0; 202 flatData.Write(&tmpChar, sizeof(tmpChar)); 203 } 204 205 flatData.Write(&fPropInfo[pi].extra_data, sizeof(fPropInfo[pi].extra_data)); 206 207 for (int32 i = 0; i < 10 && fPropInfo[pi].commands[i] != 0; i++) { 208 flatData.Write(&fPropInfo[pi].commands[i], sizeof(fPropInfo[pi].commands[i])); 209 } 210 tmpInt = 0; 211 flatData.Write(&tmpInt, sizeof(tmpInt)); 212 213 for (int32 i = 0; i < 10 && fPropInfo[pi].specifiers[i] != 0; i++) { 214 flatData.Write(&fPropInfo[pi].specifiers[i], sizeof(fPropInfo[pi].specifiers[i])); 215 } 216 tmpInt = 0; 217 flatData.Write(&tmpInt, sizeof(tmpInt)); 218 } 219 220 // Type chunks 221 for (int32 pi = 0; fPropInfo[pi].name != NULL; pi++) { 222 for (int32 i = 0; i < 10 && fPropInfo[pi].types[i] != 0; i++) { 223 flatData.Write(&fPropInfo[pi].types[i], sizeof(fPropInfo[pi].types[i])); 224 } 225 tmpInt = 0; 226 flatData.Write(&tmpInt, sizeof(tmpInt)); 227 228 for (int32 i = 0; i < 3 && fPropInfo[pi].ctypes[i].pairs[0].name != 0; i++) { 229 for (int32 j = 0; j < 5 && fPropInfo[pi].ctypes[i].pairs[j].name != 0; j++) { 230 flatData.Write(fPropInfo[pi].ctypes[i].pairs[j].name, 231 strlen(fPropInfo[pi].ctypes[i].pairs[j].name) + 1); 232 flatData.Write(&fPropInfo[pi].ctypes[i].pairs[j].type, 233 sizeof(fPropInfo[pi].ctypes[i].pairs[j].type)); 234 } 235 tmpInt = 0; 236 flatData.Write(&tmpInt, sizeof(tmpInt)); 237 } 238 tmpInt = 0; 239 flatData.Write(&tmpInt, sizeof(tmpInt)); 240 } 241 } 242 243 if (fValueInfo) { 244 // Value Chunks 245 flatData.Write(&fValueCount, sizeof(fValueCount)); 246 for (int32 vi = 0; fValueInfo[vi].name != NULL; vi++) { 247 flatData.Write(&fValueInfo[vi].kind, sizeof(fValueInfo[vi].kind)); 248 flatData.Write(&fValueInfo[vi].value, sizeof(fValueInfo[vi].value)); 249 flatData.Write(fValueInfo[vi].name, strlen(fValueInfo[vi].name) + 1); 250 if (fValueInfo[vi].usage) { 251 flatData.Write(fValueInfo[vi].usage, strlen(fValueInfo[vi].usage) + 1); 252 } 253 else { 254 tmpChar = 0; 255 flatData.Write(&tmpChar, sizeof(tmpChar)); 256 } 257 flatData.Write(&fValueInfo[vi].extra_data, sizeof(fValueInfo[vi].extra_data)); 258 } 259 } 260 261 return B_OK; 262 } 263 //------------------------------------------------------------------------------ 264 bool BPropertyInfo::AllowsTypeCode(type_code code) const 265 { 266 return (code == B_PROPERTY_INFO_TYPE); 267 } 268 //------------------------------------------------------------------------------ 269 status_t BPropertyInfo::Unflatten(type_code code, const void *buffer, 270 ssize_t numBytes) 271 { 272 if (!AllowsTypeCode(code)) 273 return B_BAD_TYPE; 274 275 if (buffer == NULL) 276 return B_BAD_VALUE; 277 278 FreeMem(); 279 280 BMemoryIO flatData(buffer, numBytes); 281 char tmpChar = B_HOST_IS_BENDIAN; 282 int32 tmpInt; 283 284 flatData.Read(&tmpChar, sizeof(tmpChar)); 285 bool swapRequired = (tmpChar != B_HOST_IS_BENDIAN); 286 287 flatData.Read(&fPropCount, sizeof(fPropCount)); 288 289 int32 flags; 290 flatData.Read(&flags, sizeof(flags)); 291 if (swapRequired) { 292 fPropCount = B_SWAP_INT32(fPropCount); 293 flags = B_SWAP_INT32(flags); 294 } 295 296 if (flags & 1) { 297 fPropInfo = static_cast<property_info *>(malloc(sizeof(property_info) * (fPropCount + 1))); 298 memset(fPropInfo, 0, (fPropCount + 1) * sizeof(property_info)); 299 300 // Main chunks 301 for (int32 pi = 0; pi < fPropCount; pi++) { 302 fPropInfo[pi].name = strdup(static_cast<const char*>(buffer) + flatData.Position()); 303 flatData.Seek(strlen(fPropInfo[pi].name) + 1, SEEK_CUR); 304 305 fPropInfo[pi].usage = strdup(static_cast<const char *>(buffer) + flatData.Position()); 306 flatData.Seek(strlen(fPropInfo[pi].usage) + 1, SEEK_CUR); 307 308 flatData.Read(&fPropInfo[pi].extra_data, sizeof(fPropInfo[pi].extra_data)); 309 if (swapRequired) { 310 fPropInfo[pi].extra_data = B_SWAP_INT32(fPropInfo[pi].extra_data); 311 } 312 313 flatData.Read(&tmpInt, sizeof(tmpInt)); 314 for (int32 i = 0; tmpInt != 0; i++) { 315 if (swapRequired) { 316 tmpInt = B_SWAP_INT32(tmpInt); 317 } 318 fPropInfo[pi].commands[i] = tmpInt; 319 flatData.Read(&tmpInt, sizeof(tmpInt)); 320 } 321 322 flatData.Read(&tmpInt, sizeof(tmpInt)); 323 for (int32 i = 0; tmpInt != 0; i++) { 324 if (swapRequired) { 325 tmpInt = B_SWAP_INT32(tmpInt); 326 } 327 fPropInfo[pi].specifiers[i] = tmpInt; 328 flatData.Read(&tmpInt, sizeof(tmpInt)); 329 } 330 } 331 332 // Type chunks 333 for (int32 pi = 0; pi < fPropCount; pi++) { 334 flatData.Read(&tmpInt, sizeof(tmpInt)); 335 for (int32 i = 0; tmpInt != 0; i++) { 336 if (swapRequired) { 337 tmpInt = B_SWAP_INT32(tmpInt); 338 } 339 fPropInfo[pi].types[i] = tmpInt; 340 flatData.Read(&tmpInt, sizeof(tmpInt)); 341 } 342 343 flatData.Read(&tmpInt, sizeof(tmpInt)); 344 for (int32 i = 0; tmpInt != 0; i++) { 345 for (int32 j = 0; tmpInt != 0; j++) { 346 flatData.Seek(-sizeof(tmpInt), SEEK_CUR); 347 fPropInfo[pi].ctypes[i].pairs[j].name = 348 strdup(static_cast<const char *>(buffer) + flatData.Position()); 349 flatData.Seek(strlen(fPropInfo[pi].ctypes[i].pairs[j].name) + 1, SEEK_CUR); 350 351 flatData.Read(&fPropInfo[pi].ctypes[i].pairs[j].type, 352 sizeof(fPropInfo[pi].ctypes[i].pairs[j].type)); 353 if (swapRequired) { 354 fPropInfo[pi].ctypes[i].pairs[j].type = 355 B_SWAP_INT32(fPropInfo[pi].ctypes[i].pairs[j].type); 356 } 357 flatData.Read(&tmpInt, sizeof(tmpInt)); 358 } 359 flatData.Read(&tmpInt, sizeof(tmpInt)); 360 } 361 } 362 } 363 364 if (flags & 2) { 365 flatData.Read(&fValueCount, sizeof(fValueCount)); 366 if (swapRequired) { 367 fValueCount = B_SWAP_INT16(fValueCount); 368 } 369 370 fValueInfo = static_cast<value_info *>(malloc(sizeof(value_info) * (fValueCount + 1))); 371 memset(fValueInfo, 0, (fValueCount + 1) * sizeof(value_info)); 372 373 for (int32 vi = 0; vi < fValueCount; vi++) 374 { 375 flatData.Read(&fValueInfo[vi].kind, sizeof(fValueInfo[vi].kind)); 376 flatData.Read(&fValueInfo[vi].value, sizeof(fValueInfo[vi].value)); 377 378 fValueInfo[vi].name = strdup(static_cast<const char *>(buffer) + flatData.Position()); 379 flatData.Seek(strlen(fValueInfo[vi].name) + 1, SEEK_CUR); 380 381 fValueInfo[vi].usage = strdup(static_cast<const char *>(buffer) + flatData.Position()); 382 flatData.Seek(strlen(fValueInfo[vi].usage) + 1, SEEK_CUR); 383 384 flatData.Read(&fValueInfo[vi].extra_data, sizeof(fValueInfo[vi].extra_data)); 385 if (swapRequired) { 386 fValueInfo[vi].kind = static_cast<value_kind>(B_SWAP_INT32(fValueInfo[vi].kind)); 387 fValueInfo[vi].value = B_SWAP_INT32(fValueInfo[vi].value); 388 fValueInfo[vi].extra_data = B_SWAP_INT32(fValueInfo[vi].extra_data); 389 } 390 } 391 } 392 393 return B_OK; 394 } 395 //------------------------------------------------------------------------------ 396 const property_info *BPropertyInfo::Properties() const 397 { 398 return fPropInfo; 399 } 400 //------------------------------------------------------------------------------ 401 const value_info *BPropertyInfo::Values() const 402 { 403 return fValueInfo; 404 } 405 //------------------------------------------------------------------------------ 406 int32 BPropertyInfo::CountProperties() const 407 { 408 return fPropCount; 409 } 410 //------------------------------------------------------------------------------ 411 int32 BPropertyInfo::CountValues() const 412 { 413 return fValueCount; 414 } 415 //------------------------------------------------------------------------------ 416 void BPropertyInfo::PrintToStream() const 417 { 418 printf(" property commands types specifiers\n"); 419 printf("--------------------------------------------------------------------------------\n"); 420 421 for (int32 pi = 0; fPropInfo[pi].name != 0; pi++) 422 { 423 // property 424 printf("%14s", fPropInfo[pi].name); 425 // commands 426 for (int32 i = 0; i < 10 && fPropInfo[pi].commands[i] != 0; i++) 427 { 428 uint32 command = fPropInfo[pi].commands[i]; 429 430 printf(" %c%c%c%-28c", (command & 0xFF000000) >> 24, 431 (command & 0xFF0000) >> 16, (command & 0xFF00) >> 8, 432 command & 0xFF); 433 } 434 // types 435 for (int32 i = 0; i < 10 && fPropInfo[pi].types[i] != 0; i++) 436 { 437 uint32 type = fPropInfo[pi].types[i]; 438 439 printf("%c%c%c%c", (type & 0xFF000000) >> 24, 440 (type & 0xFF0000) >> 16, (type & 0xFF00) >> 8, type & 0xFF); 441 } 442 // specifiers 443 for (int32 i = 0; i < 10 && fPropInfo[pi].specifiers[i] != 0; i++) 444 { 445 uint32 spec = fPropInfo[pi].specifiers[i]; 446 447 printf("%d", spec); 448 } 449 printf("\n"); 450 } 451 } 452 //------------------------------------------------------------------------------ 453 bool BPropertyInfo::FindCommand(uint32 what, int32 index, property_info *p) 454 { 455 bool result = false; 456 457 if (p->commands[0] == 0) { 458 result = true; 459 } else if (index == 0) { 460 for (int32 i = 0; i < 10 && p->commands[i] != 0; i++) { 461 if (p->commands[i] == what) { 462 result = true; 463 } 464 } 465 } 466 467 return(result); 468 } 469 //------------------------------------------------------------------------------ 470 bool BPropertyInfo::FindSpecifier(uint32 form, property_info *p) 471 { 472 bool result = false; 473 474 if (p->specifiers[0] == 0) { 475 result = true; 476 } else { 477 for (int32 i = 0; i < 10 && p->specifiers[i] != 0; i++) { 478 if (p->specifiers[i] == form) { 479 result = true; 480 } 481 } 482 } 483 484 return(result); 485 } 486 //------------------------------------------------------------------------------ 487 void BPropertyInfo::_ReservedPropertyInfo1() {} 488 void BPropertyInfo::_ReservedPropertyInfo2() {} 489 void BPropertyInfo::_ReservedPropertyInfo3() {} 490 void BPropertyInfo::_ReservedPropertyInfo4() {} 491 //------------------------------------------------------------------------------ 492 BPropertyInfo::BPropertyInfo(const BPropertyInfo &) 493 { 494 } 495 //------------------------------------------------------------------------------ 496 BPropertyInfo &BPropertyInfo::operator=(const BPropertyInfo &) 497 { 498 return *this; 499 } 500 //------------------------------------------------------------------------------ 501 void BPropertyInfo::FreeMem() 502 { 503 int i, j, k; 504 505 if (!fInHeap) { 506 return; 507 } 508 509 if (fPropInfo != NULL) { 510 for(i = 0; i < fPropCount; i++) { 511 if (fPropInfo[i].name != NULL) { 512 free(fPropInfo[i].name); 513 } 514 if (fPropInfo[i].usage != NULL) { 515 free(fPropInfo[i].usage); 516 } 517 for(j = 0; j < 3; j++) { 518 for(k = 0; k < 5; k++) { 519 if (fPropInfo[i].ctypes[j].pairs[k].name == NULL) { 520 break; 521 } else { 522 free(fPropInfo[i].ctypes[j].pairs[k].name); 523 } 524 } 525 if (fPropInfo[i].ctypes[j].pairs[0].name == NULL) { 526 break; 527 } 528 } 529 } 530 free(fPropInfo); 531 fPropInfo = NULL; 532 fPropCount = 0; 533 } 534 535 if (fValueInfo != NULL) { 536 for(i = 0; i < fValueCount; i++) { 537 if (fValueInfo[i].name != NULL) { 538 free(fValueInfo[i].name); 539 } 540 if (fValueInfo[i].usage != NULL) { 541 free(fValueInfo[i].usage); 542 } 543 } 544 free(fValueInfo); 545 fValueInfo = NULL; 546 fValueCount = 0; 547 } 548 549 fInHeap = false; 550 } 551 //------------------------------------------------------------------------------ 552 553 /* 554 * $Log $ 555 * 556 * $Id $ 557 * 558 */ 559