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 19 using namespace std; 20 21 22 TransportException::TransportException(const string& what) 23 : 24 fWhat(what) 25 { 26 } 27 28 29 const char* 30 TransportException::What() const 31 { 32 return fWhat.c_str(); 33 } 34 35 36 Transport::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 95 Transport::~Transport() 96 { 97 if (fExitTransport) { 98 (*fExitTransport)(); 99 } 100 if (fImage >= 0) { 101 unload_add_on(fImage); 102 } 103 } 104 105 106 bool 107 Transport::CheckAbort() const 108 { 109 return fDataStream == 0; 110 } 111 112 113 const 114 string &Transport::LastError() const 115 { 116 return fLastErrorString; 117 } 118 119 120 bool 121 Transport::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 130 void 131 Transport::SetLastError(const char *e) 132 { 133 fLastErrorString = e; 134 fAbort = true; 135 } 136 137 138 void 139 Transport::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