1 /*****************************************************************************/ 2 // STXTTranslator 3 // Written by Michael Wilber, OBOS Translation Kit Team 4 // 5 // STXTTranslator.cpp 6 // 7 // This BTranslator based object is for opening and writing 8 // StyledEdit (STXT) files. 9 // 10 // 11 // Copyright (c) 2002 OpenBeOS Project 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a 14 // copy of this software and associated documentation files (the "Software"), 15 // to deal in the Software without restriction, including without limitation 16 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 // and/or sell copies of the Software, and to permit persons to whom the 18 // Software is furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included 21 // in all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 // DEALINGS IN THE SOFTWARE. 30 /*****************************************************************************/ 31 32 #include <string.h> 33 #include <stdio.h> 34 #include "STXTTranslator.h" 35 #include "STXTView.h" 36 37 #define READ_BUFFER_SIZE 2048 38 #define DATA_BUFFER_SIZE 64 39 40 // The input formats that this translator supports. 41 translation_format gInputFormats[] = { 42 { 43 B_TRANSLATOR_TEXT, 44 B_TRANSLATOR_TEXT, 45 TEXT_IN_QUALITY, 46 TEXT_IN_CAPABILITY, 47 "text/plain", 48 "Plain text file" 49 }, 50 { 51 B_STYLED_TEXT_FORMAT, 52 B_TRANSLATOR_TEXT, 53 STXT_IN_QUALITY, 54 STXT_IN_CAPABILITY, 55 "text/x-vnd.Be-stxt", 56 "Be styled text file" 57 } 58 }; 59 60 // The output formats that this translator supports. 61 translation_format gOutputFormats[] = { 62 { 63 B_TRANSLATOR_TEXT, 64 B_TRANSLATOR_TEXT, 65 TEXT_OUT_QUALITY, 66 TEXT_OUT_CAPABILITY, 67 "text/plain", 68 "Plain text file" 69 }, 70 { 71 B_STYLED_TEXT_FORMAT, 72 B_TRANSLATOR_TEXT, 73 STXT_OUT_QUALITY, 74 STXT_OUT_CAPABILITY, 75 "text/x-vnd.Be-stxt", 76 "Be styled text file" 77 } 78 }; 79 80 // Default settings for the Translator 81 TranSetting gDefaultSettings[] = { 82 {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, 83 {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false} 84 }; 85 86 // --------------------------------------------------------------- 87 // make_nth_translator 88 // 89 // Creates a STXTTranslator object to be used by BTranslatorRoster 90 // 91 // Preconditions: 92 // 93 // Parameters: n, The translator to return. Since 94 // STXTTranslator only publishes one 95 // translator, it only returns a 96 // STXTTranslator if n == 0 97 // 98 // you, The image_id of the add-on that 99 // contains code (not used). 100 // 101 // flags, Has no meaning yet, should be 0. 102 // 103 // Postconditions: 104 // 105 // Returns: NULL if n is not zero, 106 // a new STXTTranslator if n is zero 107 // --------------------------------------------------------------- 108 BTranslator * 109 make_nth_translator(int32 n, image_id you, uint32 flags, ...) 110 { 111 if (!n) 112 return new STXTTranslator(); 113 else 114 return NULL; 115 } 116 117 // --------------------------------------------------------------- 118 // Constructor 119 // 120 // Sets up the version info and the name of the translator so that 121 // these values can be returned when they are requested. 122 // 123 // Preconditions: 124 // 125 // Parameters: 126 // 127 // Postconditions: 128 // 129 // Returns: 130 // --------------------------------------------------------------- 131 STXTTranslator::STXTTranslator() 132 : BaseTranslator("StyledEdit Files", "StyledEdit files translator", 133 STXT_TRANSLATOR_VERSION, 134 gInputFormats, sizeof(gInputFormats) / sizeof(translation_format), 135 gOutputFormats, sizeof(gOutputFormats) / sizeof(translation_format), 136 "STXTTranslator_Settings", 137 gDefaultSettings, sizeof(gDefaultSettings) / sizeof(TranSetting), 138 B_TRANSLATOR_TEXT, B_STYLED_TEXT_FORMAT) 139 { 140 } 141 142 // --------------------------------------------------------------- 143 // Destructor 144 // 145 // Does nothing 146 // 147 // Preconditions: 148 // 149 // Parameters: 150 // 151 // Postconditions: 152 // 153 // Returns: 154 // --------------------------------------------------------------- 155 STXTTranslator::~STXTTranslator() 156 { 157 } 158 159 // --------------------------------------------------------------- 160 // identify_stxt_header 161 // 162 // Determines if the data in inSource is of the STXT format. 163 // 164 // Preconditions: 165 // 166 // Parameters: header, the STXT stream header read in by 167 // Identify() or Translate() 168 // 169 // inSource, The stream with the STXT data 170 // 171 // outInfo, information about the type of data 172 // from inSource is stored here 173 // 174 // outType, the desired output type for the 175 // data in inSource 176 // 177 // ptxtheader if this is not NULL, the TEXT 178 // header from inSource is copied 179 // to it 180 // 181 // Postconditions: 182 // 183 // Returns: B_OK, if the data appears to be in the STXT format, 184 // B_NO_TRANSLATOR, if the data is not in the STXT format or 185 // returns B_ERROR if errors were encountered in trying to 186 // determine the format, or another error code if there was an 187 // error calling BPostionIO::Read() 188 // --------------------------------------------------------------- 189 status_t 190 identify_stxt_header(const TranslatorStyledTextStreamHeader &header, 191 BPositionIO *inSource, translator_info *outInfo, uint32 outType, 192 TranslatorStyledTextTextHeader *ptxtheader = NULL) 193 { 194 const ssize_t ktxtsize = sizeof(TranslatorStyledTextTextHeader); 195 const ssize_t kstylsize = sizeof(TranslatorStyledTextStyleHeader); 196 197 uint8 buffer[max(ktxtsize, kstylsize)]; 198 199 // Check the TEXT header 200 TranslatorStyledTextTextHeader txtheader; 201 if (inSource->Read(buffer, ktxtsize) != ktxtsize) 202 return B_NO_TRANSLATOR; 203 204 memcpy(&txtheader, buffer, ktxtsize); 205 if (swap_data(B_UINT32_TYPE, &txtheader, ktxtsize, 206 B_SWAP_BENDIAN_TO_HOST) != B_OK) 207 return B_ERROR; 208 209 if (txtheader.header.magic != 'TEXT' || 210 txtheader.header.header_size != 211 sizeof(TranslatorStyledTextTextHeader) || 212 txtheader.charset != B_UNICODE_UTF8) 213 return B_NO_TRANSLATOR; 214 215 // skip the text data 216 off_t seekresult, pos; 217 pos = header.header.header_size + 218 txtheader.header.header_size + 219 txtheader.header.data_size; 220 seekresult = inSource->Seek(txtheader.header.data_size, 221 SEEK_CUR); 222 if (seekresult < pos) 223 return B_NO_TRANSLATOR; 224 if (seekresult > pos) 225 return B_ERROR; 226 227 // check the STYL header (not all STXT files have this) 228 ssize_t read = 0; 229 TranslatorStyledTextStyleHeader stylheader; 230 read = inSource->Read(buffer, kstylsize); 231 if (read < 0) 232 return read; 233 if (read != kstylsize && read != 0) 234 return B_NO_TRANSLATOR; 235 236 // If there is a STYL header 237 if (read == kstylsize) { 238 memcpy(&stylheader, buffer, kstylsize); 239 if (swap_data(B_UINT32_TYPE, &stylheader, kstylsize, 240 B_SWAP_BENDIAN_TO_HOST) != B_OK) 241 return B_ERROR; 242 243 if (stylheader.header.magic != 'STYL' || 244 stylheader.header.header_size != 245 sizeof(TranslatorStyledTextStyleHeader)) 246 return B_NO_TRANSLATOR; 247 } 248 249 // if output TEXT header is supplied, fill it with data 250 if (ptxtheader) { 251 ptxtheader->header.magic = txtheader.header.magic; 252 ptxtheader->header.header_size = txtheader.header.header_size; 253 ptxtheader->header.data_size = txtheader.header.data_size; 254 ptxtheader->charset = txtheader.charset; 255 } 256 257 // return information about the data in the stream 258 outInfo->type = B_STYLED_TEXT_FORMAT; 259 outInfo->group = B_TRANSLATOR_TEXT; 260 outInfo->quality = STXT_IN_QUALITY; 261 outInfo->capability = STXT_IN_CAPABILITY; 262 strcpy(outInfo->name, "Be styled text file"); 263 strcpy(outInfo->MIME, "text/x-vnd.Be-stxt"); 264 265 return B_OK; 266 } 267 268 // --------------------------------------------------------------- 269 // identify_txt_header 270 // 271 // Determines if the data in inSource is of the UTF8 plain 272 // text format. 273 // 274 // Preconditions: data must point to a buffer at least 275 // DATA_BUFFER_SIZE bytes long 276 // 277 // Parameters: data, buffer containing data already read 278 // from the stream 279 // 280 // nread, number of bytes that have already 281 // been read from the stream 282 // 283 // header, the STXT stream header read in by 284 // Identify() or Translate() 285 // 286 // inSource, The stream with the STXT data 287 // 288 // outInfo, information about the type of data 289 // from inSource is stored here 290 // 291 // outType the desired output type for the 292 // data in inSource 293 // 294 // 295 // Postconditions: 296 // 297 // Returns: B_OK, if the data appears to be in the STXT format, 298 // B_NO_TRANSLATOR, if the data is not in the STXT format or 299 // returns B_ERROR if errors were encountered in trying to 300 // determine the format 301 // --------------------------------------------------------------- 302 status_t 303 identify_txt_header(uint8 *data, int32 nread, 304 BPositionIO *inSource, translator_info *outInfo, uint32 outType) 305 { 306 float capability = TEXT_IN_CAPABILITY; 307 uint8 ch; 308 ssize_t readlater = 0; 309 readlater = inSource->Read(data + nread, DATA_BUFFER_SIZE - nread); 310 if (readlater < 0) 311 return B_NO_TRANSLATOR; 312 313 nread += readlater; 314 for (int32 i = 0; i < nread; i++) { 315 ch = data[i]; 316 // if any null characters or control characters 317 // are found, reduce our ability to handle the data 318 if (ch < 0x20 && 319 ch != 0x08 && // backspace 320 ch != 0x09 && // tab 321 ch != 0x0A && // line feed 322 ch != 0x0C && // form feed 323 ch != 0x0D) { // carriage return 324 capability *= 0.6; 325 break; 326 } 327 } 328 329 // return information about the data in the stream 330 outInfo->type = B_TRANSLATOR_TEXT; 331 outInfo->group = B_TRANSLATOR_TEXT; 332 outInfo->quality = TEXT_IN_QUALITY; 333 outInfo->capability = capability; 334 strcpy(outInfo->name, "Plain text file"); 335 strcpy(outInfo->MIME, "text/plain"); 336 337 return B_OK; 338 } 339 340 // --------------------------------------------------------------- 341 // Identify 342 // 343 // Examines the data from inSource and determines if it is in a 344 // format that this translator knows how to work with. 345 // 346 // Preconditions: 347 // 348 // Parameters: inSource, where the data to examine is 349 // 350 // inFormat, a hint about the data in inSource, 351 // it is ignored since it is only a hint 352 // 353 // ioExtension, configuration settings for the 354 // translator (not used) 355 // 356 // outInfo, information about what data is in 357 // inSource and how well this translator 358 // can handle that data is stored here 359 // 360 // outType, The format that the user wants 361 // the data in inSource to be 362 // converted to 363 // 364 // Postconditions: 365 // 366 // Returns: B_NO_TRANSLATOR, if this translator can't handle 367 // the data in inSource 368 // 369 // B_ERROR, if there was an error converting the data to the host 370 // format 371 // 372 // B_BAD_VALUE, if the settings in ioExtension are bad 373 // 374 // B_OK, if this translator understand the data and there were 375 // no errors found 376 // 377 // Other errors if BPositionIO::Read() returned an error value 378 // --------------------------------------------------------------- 379 status_t 380 STXTTranslator::Identify(BPositionIO *inSource, 381 const translation_format *inFormat, BMessage *ioExtension, 382 translator_info *outInfo, uint32 outType) 383 { 384 if (!outType) 385 outType = B_TRANSLATOR_TEXT; 386 if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT) 387 return B_NO_TRANSLATOR; 388 389 const ssize_t kstxtsize = sizeof(TranslatorStyledTextStreamHeader); 390 391 uint8 buffer[DATA_BUFFER_SIZE]; 392 status_t nread = 0; 393 // Read in the header to determine 394 // if the data is supported 395 nread = inSource->Read(buffer, kstxtsize); 396 if (nread < 0) 397 return nread; 398 399 // read in enough data to fill the stream header 400 if (nread == kstxtsize) { 401 TranslatorStyledTextStreamHeader header; 402 memcpy(&header, buffer, kstxtsize); 403 if (swap_data(B_UINT32_TYPE, &header, kstxtsize, 404 B_SWAP_BENDIAN_TO_HOST) != B_OK) 405 return B_ERROR; 406 407 if (header.header.magic == B_STYLED_TEXT_FORMAT && 408 header.header.header_size == 409 sizeof(TranslatorStyledTextStreamHeader) && 410 header.header.data_size == 0 && 411 header.version == 100) 412 return identify_stxt_header(header, inSource, outInfo, outType); 413 } 414 415 // if the data is not styled text, check if it is plain text 416 return identify_txt_header(buffer, nread, inSource, outInfo, outType); 417 } 418 419 // --------------------------------------------------------------- 420 // translate_from_stxt 421 // 422 // Translates the data in inSource to the type outType and stores 423 // the translated data in outDestination. 424 // 425 // Preconditions: 426 // 427 // Parameters: inSource, the data to be translated 428 // 429 // outDestination, where the translated data is 430 // put 431 // 432 // outType, the type to convert inSource to 433 // 434 // txtheader, the TEXT header from inSource 435 // 436 // 437 // Postconditions: 438 // 439 // Returns: B_BAD_VALUE, if outType is invalid 440 // 441 // B_NO_TRANSLATOR, if this translator doesn't understand the data 442 // 443 // B_ERROR, if there was an error allocating memory or converting 444 // data 445 // 446 // B_OK, if all went well 447 // --------------------------------------------------------------- 448 status_t 449 translate_from_stxt(BPositionIO *inSource, BPositionIO *outDestination, 450 uint32 outType, const TranslatorStyledTextTextHeader &txtheader) 451 { 452 if (inSource->Seek(0, SEEK_SET) != 0) 453 return B_ERROR; 454 455 const ssize_t kstxtsize = sizeof(TranslatorStyledTextStreamHeader); 456 const ssize_t ktxtsize = sizeof(TranslatorStyledTextTextHeader); 457 458 bool btoplain; 459 if (outType == B_TRANSLATOR_TEXT) 460 btoplain = true; 461 else if (outType == B_STYLED_TEXT_FORMAT) 462 btoplain = false; 463 else 464 return B_BAD_VALUE; 465 466 uint8 buffer[READ_BUFFER_SIZE]; 467 ssize_t nread = 0, nwritten = 0, nreed = 0, ntotalread = 0; 468 469 // skip to the actual text data when outputting a 470 // plain text file 471 if (btoplain) { 472 if (inSource->Seek(kstxtsize + ktxtsize, SEEK_CUR) != 473 kstxtsize + ktxtsize) 474 return B_ERROR; 475 } 476 477 // Read data from inSource 478 // When outputing B_TRANSLATOR_TEXT, the loop stops when all of 479 // the text data has been read and written. 480 // When outputting B_STYLED_TEXT_FORMAT, the loop stops when all 481 // of the data from inSource has been read and written. 482 if (btoplain) 483 nreed = min(READ_BUFFER_SIZE, 484 txtheader.header.data_size - ntotalread); 485 else 486 nreed = READ_BUFFER_SIZE; 487 nread = inSource->Read(buffer, nreed); 488 while (nread > 0) { 489 nwritten = outDestination->Write(buffer, nread); 490 if (nwritten != nread) 491 return B_ERROR; 492 493 if (btoplain) { 494 ntotalread += nread; 495 nreed = min(READ_BUFFER_SIZE, 496 txtheader.header.data_size - ntotalread); 497 } else 498 nreed = READ_BUFFER_SIZE; 499 nread = inSource->Read(buffer, nreed); 500 } 501 502 if (btoplain && static_cast<ssize_t>(txtheader.header.data_size) != 503 ntotalread) 504 // If not all of the text data was able to be read... 505 return B_NO_TRANSLATOR; 506 else 507 return B_OK; 508 } 509 510 // --------------------------------------------------------------- 511 // output_headers 512 // 513 // Outputs the Stream and Text headers from the B_STYLED_TEXT_FORMAT 514 // to outDestination, setting the data_size member of the text header 515 // to text_data_size 516 // 517 // Preconditions: 518 // 519 // Parameters: outDestination, where the translated data is 520 // put 521 // 522 // text_data_size, number of bytes in data section 523 // of the TEXT header 524 // 525 // 526 // Postconditions: 527 // 528 // Returns: 529 // 530 // B_ERROR, if there was an error writing to outDestination or 531 // an error with converting the byte order 532 // 533 // B_OK, if all went well 534 // --------------------------------------------------------------- 535 status_t 536 output_headers(BPositionIO *outDestination, uint32 text_data_size) 537 { 538 const int32 kHeadersSize = sizeof(TranslatorStyledTextStreamHeader) + 539 sizeof(TranslatorStyledTextTextHeader); 540 status_t result; 541 TranslatorStyledTextStreamHeader stxtheader; 542 TranslatorStyledTextTextHeader txtheader; 543 544 uint8 buffer[kHeadersSize]; 545 546 stxtheader.header.magic = 'STXT'; 547 stxtheader.header.header_size = sizeof(TranslatorStyledTextStreamHeader); 548 stxtheader.header.data_size = 0; 549 stxtheader.version = 100; 550 memcpy(buffer, &stxtheader, stxtheader.header.header_size); 551 552 txtheader.header.magic = 'TEXT'; 553 txtheader.header.header_size = sizeof(TranslatorStyledTextTextHeader); 554 txtheader.header.data_size = text_data_size; 555 txtheader.charset = B_UNICODE_UTF8; 556 memcpy(buffer + stxtheader.header.header_size, &txtheader, 557 txtheader.header.header_size); 558 559 // write out headers in Big Endian byte order 560 result = swap_data(B_UINT32_TYPE, buffer, kHeadersSize, 561 B_SWAP_HOST_TO_BENDIAN); 562 if (result == B_OK) { 563 ssize_t nwritten = 0; 564 nwritten = outDestination->Write(buffer, kHeadersSize); 565 if (nwritten != kHeadersSize) 566 return B_ERROR; 567 else 568 return B_OK; 569 } 570 571 return result; 572 } 573 574 // --------------------------------------------------------------- 575 // output_styles 576 // 577 // Writes out the actual style information into outDestination 578 // using the data from pflatRunArray 579 // 580 // Preconditions: 581 // 582 // Parameters: outDestination, where the translated data is 583 // put 584 // 585 // text_size, size in bytes of the text in 586 // outDestination 587 // 588 // data_size, size of pflatRunArray 589 // 590 // Postconditions: 591 // 592 // Returns: 593 // 594 // B_ERROR, if there was an error writing to outDestination or 595 // an error with converting the byte order 596 // 597 // B_OK, if all went well 598 // --------------------------------------------------------------- 599 status_t 600 output_styles(BPositionIO *outDestination, uint32 text_size, 601 uint8 *pflatRunArray, ssize_t data_size) 602 { 603 const ssize_t kstylsize = sizeof(TranslatorStyledTextStyleHeader); 604 605 uint8 buffer[kstylsize]; 606 607 // output STYL header 608 TranslatorStyledTextStyleHeader stylheader; 609 stylheader.header.magic = 'STYL'; 610 stylheader.header.header_size = 611 sizeof(TranslatorStyledTextStyleHeader); 612 stylheader.header.data_size = data_size; 613 stylheader.apply_offset = 0; 614 stylheader.apply_length = text_size; 615 616 memcpy(buffer, &stylheader, kstylsize); 617 if (swap_data(B_UINT32_TYPE, buffer, kstylsize, 618 B_SWAP_HOST_TO_BENDIAN) != B_OK) 619 return B_ERROR; 620 if (outDestination->Write(buffer, kstylsize) != kstylsize) 621 return B_ERROR; 622 623 // output actual style information 624 if (outDestination->Write(pflatRunArray, 625 data_size) != data_size) 626 return B_ERROR; 627 628 return B_OK; 629 } 630 631 // --------------------------------------------------------------- 632 // translate_from_text 633 // 634 // Convert the plain text (UTF8) from inSource to plain or 635 // styled text in outDestination 636 // 637 // Preconditions: 638 // 639 // Parameters: inSource, the data to be translated 640 // 641 // outDestination, where the translated data is 642 // put 643 // 644 // outType, the type to convert inSource to 645 // 646 // Postconditions: 647 // 648 // Returns: B_BAD_VALUE, if outType is not supported 649 // 650 // B_NO_MEMORY, if couldn't allocate enough memory to read in 651 // the styled text run array 652 // 653 // B_NO_TRANSLATOR, if this translator doesn't understand the data 654 // 655 // B_ERROR, if there was an error reading or writing data or 656 // converting data 657 // 658 // B_OK, if all went well 659 // --------------------------------------------------------------- 660 status_t 661 translate_from_text(BPositionIO *inSource, BPositionIO *outDestination, 662 uint32 outType) 663 { 664 // find the length of the text 665 off_t size = 0; 666 size = inSource->Seek(0, SEEK_END); 667 if (size < 0) 668 return B_ERROR; 669 670 if (inSource->Seek(0, SEEK_SET) != 0) 671 return B_ERROR; 672 673 bool btoplain; 674 if (outType == B_TRANSLATOR_TEXT) 675 btoplain = true; 676 else if (outType == B_STYLED_TEXT_FORMAT) 677 btoplain = false; 678 else 679 return B_BAD_VALUE; 680 681 // output styled text headers if outputting 682 // in the B_STYLED_TEXT_FORMAT 683 if (!btoplain) { 684 status_t headresult; 685 headresult = output_headers(outDestination, 686 static_cast<uint32>(size)); 687 if (headresult != B_OK) 688 return headresult; 689 } 690 691 uint8 buffer[READ_BUFFER_SIZE]; 692 ssize_t nread = 0, nwritten = 0; 693 694 // output the actual text part of the data 695 nread = inSource->Read(buffer, READ_BUFFER_SIZE); 696 while (nread > 0) { 697 nwritten = outDestination->Write(buffer, nread); 698 if (nwritten != nread) 699 return B_ERROR; 700 701 nread = inSource->Read(buffer, READ_BUFFER_SIZE); 702 } 703 704 // Read file attributes if outputting styled data 705 // and inSource is a BFile object 706 status_t result = B_OK; 707 if (!btoplain) { 708 BFile *pfile = NULL; 709 pfile = dynamic_cast<BFile *>(inSource); 710 if (pfile) { 711 const char *kAttrName = "styles"; 712 attr_info info; 713 if (pfile->GetAttrInfo(kAttrName, &info) == B_OK) { 714 if (info.type != B_RAW_TYPE) 715 return B_NO_TRANSLATOR; 716 if (info.size < 160) 717 return B_NO_TRANSLATOR; 718 719 uint8 *pflatRunArray = new uint8[info.size]; 720 if (pflatRunArray) { 721 ssize_t amtread = pfile->ReadAttr(kAttrName, 722 B_RAW_TYPE, 0, pflatRunArray, info.size); 723 724 // write style data 725 if (amtread == info.size) { 726 result = output_styles(outDestination, 727 size, pflatRunArray, info.size); 728 } else 729 result = B_ERROR; 730 731 delete[] pflatRunArray; 732 pflatRunArray = NULL; 733 734 } else 735 result = B_NO_MEMORY; 736 } 737 } 738 } 739 740 return result; 741 } 742 743 // --------------------------------------------------------------- 744 // Translate 745 // 746 // Translates the data in inSource to the type outType and stores 747 // the translated data in outDestination. 748 // 749 // Preconditions: 750 // 751 // Parameters: inSource, the data to be translated 752 // 753 // inInfo, hint about the data in inSource (not used) 754 // 755 // ioExtension, configuration options for the 756 // translator 757 // 758 // outType, the type to convert inSource to 759 // 760 // outDestination, where the translated data is 761 // put 762 // 763 // Postconditions: 764 // 765 // Returns: B_BAD_VALUE, if the options in ioExtension are bad 766 // 767 // B_NO_TRANSLATOR, if this translator doesn't understand the data 768 // 769 // B_ERROR, if there was an error allocating memory or converting 770 // data 771 // 772 // B_OK, if all went well 773 // --------------------------------------------------------------- 774 status_t 775 STXTTranslator::Translate(BPositionIO *inSource, 776 const translator_info *inInfo, BMessage *ioExtension, 777 uint32 outType, BPositionIO *outDestination) 778 { 779 if (!outType) 780 outType = B_TRANSLATOR_TEXT; 781 if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT) 782 return B_NO_TRANSLATOR; 783 784 const ssize_t kstxtsize = sizeof(TranslatorStyledTextStreamHeader); 785 uint8 buffer[DATA_BUFFER_SIZE]; 786 status_t nread = 0, result; 787 translator_info outInfo; 788 // Read in the header to determine 789 // if the data is supported 790 nread = inSource->Read(buffer, kstxtsize); 791 if (nread < 0) 792 return nread; 793 794 // read in enough data to fill the stream header 795 if (nread == kstxtsize) { 796 TranslatorStyledTextStreamHeader header; 797 memcpy(&header, buffer, kstxtsize); 798 if (swap_data(B_UINT32_TYPE, &header, kstxtsize, 799 B_SWAP_BENDIAN_TO_HOST) != B_OK) 800 return B_ERROR; 801 802 if (header.header.magic == B_STYLED_TEXT_FORMAT && 803 header.header.header_size == 804 sizeof(TranslatorStyledTextStreamHeader) && 805 header.header.data_size == 0 && 806 header.version == 100) { 807 808 TranslatorStyledTextTextHeader txtheader; 809 result = identify_stxt_header(header, inSource, &outInfo, outType, 810 &txtheader); 811 return translate_from_stxt(inSource, outDestination, outType, 812 txtheader); 813 } 814 } 815 816 // if the data is not styled text, check if it is ASCII text 817 result = identify_txt_header(buffer, nread, inSource, &outInfo, outType); 818 if (result == B_OK) 819 return translate_from_text(inSource, outDestination, outType); 820 else 821 return result; 822 } 823 824 BView * 825 STXTTranslator::NewConfigView(TranslatorSettings *settings) 826 { 827 return new STXTView(BRect(0, 0, 225, 175), "STXTTranslator Settings", 828 B_FOLLOW_ALL, B_WILL_DRAW, settings); 829 } 830 831