1/* 2 * Transport.cpp 3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved. 4 */ 5 6#include <FindDirectory.h> 7#include <Message.h> 8#include <Directory.h> 9#include <DataIO.h> 10#include <File.h> 11#include <Path.h> 12#include <image.h> 13 14#include "Transport.h" 15#include "PrinterData.h" 16#include "DbgMsg.h" 17 18 19using namespace std; 20 21 22TransportException::TransportException(const string& what) 23 : 24 fWhat(what) 25{ 26} 27 28 29const char* 30TransportException::What() const 31{ 32 return fWhat.c_str(); 33} 34 35 36Transport::Transport(const PrinterData *printerData) 37 : 38 fImage(-1), 39 fInitTransport(0), 40 fExitTransport(0), 41 fDataStream(0), 42 fAbort(false) 43{ 44 const directory_which paths[] = { 45 B_USER_ADDONS_DIRECTORY, 46 B_COMMON_ADDONS_DIRECTORY, 47 B_BEOS_ADDONS_DIRECTORY, 48 }; 49 BPath path; 50 for (uint32 i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) { 51 if (find_directory(paths[i], &path) != B_OK) 52 continue; 53 path.Append("Print/transport"); 54 path.Append(printerData->GetTransport().c_str()); 55 DBGMSG(("load_add_on: %s\n", path.Path())); 56 fImage = load_add_on(path.Path()); 57 if (fImage >= 0) 58 break; 59 } 60 61 if (fImage < 0) { 62 SetLastError("cannot load a transport add-on"); 63 return; 64 } 65 66 DBGMSG(("image id = %d\n", (int)fImage)); 67 68 get_image_symbol(fImage, "init_transport", B_SYMBOL_TYPE_TEXT, (void **)&fInitTransport); 69 get_image_symbol(fImage, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **)&fExitTransport); 70 71 if (fInitTransport == NULL) { 72 SetLastError("get_image_symbol failed."); 73 DBGMSG(("init_transport is NULL\n")); 74 } 75 76 if (fExitTransport == NULL) { 77 SetLastError("get_image_symbol failed."); 78 DBGMSG(("exit_transport is NULL\n")); 79 } 80 81 if (fInitTransport) { 82 string spool_path; 83 printerData->GetPath(spool_path); 84 BMessage *msg = new BMessage('TRIN'); 85 msg->AddString("printer_file", spool_path.c_str()); 86 fDataStream = (*fInitTransport)(msg); 87 delete msg; 88 if (fDataStream == 0) { 89 SetLastError("init_transport failed."); 90 } 91 } 92} 93 94 95Transport::~Transport() 96{ 97 if (fExitTransport) { 98 (*fExitTransport)(); 99 } 100 if (fImage >= 0) { 101 unload_add_on(fImage); 102 } 103} 104 105 106bool 107Transport::CheckAbort() const 108{ 109 return fDataStream == 0; 110} 111 112 113const 114string &Transport::LastError() const 115{ 116 return fLastErrorString; 117} 118 119 120bool 121Transport::IsPrintToFileCanceled() const 122{ 123 // The BeOS "Print To File" transport add-on returns a non-NULL BDataIO * 124 // even after user filepanel cancellation! 125 BFile* file = dynamic_cast<BFile*>(fDataStream); 126 return file != NULL && file->InitCheck() != B_OK; 127} 128 129 130void 131Transport::SetLastError(const char *e) 132{ 133 fLastErrorString = e; 134 fAbort = true; 135} 136 137 138void 139Transport::Write(const void* buffer, size_t size) throw(TransportException) 140{ 141 if (fDataStream) { 142 if (size == (size_t)fDataStream->Write(buffer, size)) { 143 return; 144 } 145 SetLastError("BDataIO::Write failed."); 146 } 147 throw TransportException(LastError()); 148} 149