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_NONPACKAGED_ADDONS_DIRECTORY, 46 B_USER_ADDONS_DIRECTORY, 47 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, 48 B_BEOS_ADDONS_DIRECTORY, 49 }; 50 BPath path; 51 for (uint32 i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) { 52 if (find_directory(paths[i], &path) != B_OK) 53 continue; 54 path.Append("Print/transport"); 55 path.Append(printerData->GetTransport().c_str()); 56 DBGMSG(("load_add_on: %s\n", path.Path())); 57 fImage = load_add_on(path.Path()); 58 if (fImage >= 0) 59 break; 60 } 61 62 if (fImage < 0) { 63 SetLastError("cannot load a transport add-on"); 64 return; 65 } 66 67 DBGMSG(("image id = %d\n", (int)fImage)); 68 69 get_image_symbol(fImage, "init_transport", B_SYMBOL_TYPE_TEXT, (void **)&fInitTransport); 70 get_image_symbol(fImage, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **)&fExitTransport); 71 72 if (fInitTransport == NULL) { 73 SetLastError("get_image_symbol failed."); 74 DBGMSG(("init_transport is NULL\n")); 75 } 76 77 if (fExitTransport == NULL) { 78 SetLastError("get_image_symbol failed."); 79 DBGMSG(("exit_transport is NULL\n")); 80 } 81 82 if (fInitTransport) { 83 string spool_path; 84 printerData->GetPath(spool_path); 85 BMessage *msg = new BMessage('TRIN'); 86 msg->AddString("printer_file", spool_path.c_str()); 87 fDataStream = (*fInitTransport)(msg); 88 delete msg; 89 if (fDataStream == 0) { 90 SetLastError("init_transport failed."); 91 } 92 } 93 } 94 95 96 Transport::~Transport() 97 { 98 if (fExitTransport) { 99 (*fExitTransport)(); 100 } 101 if (fImage >= 0) { 102 unload_add_on(fImage); 103 } 104 } 105 106 107 bool 108 Transport::CheckAbort() const 109 { 110 return fDataStream == 0; 111 } 112 113 114 const 115 string &Transport::LastError() const 116 { 117 return fLastErrorString; 118 } 119 120 121 bool 122 Transport::IsPrintToFileCanceled() const 123 { 124 // The BeOS "Print To File" transport add-on returns a non-NULL BDataIO * 125 // even after user filepanel cancellation! 126 BFile* file = dynamic_cast<BFile*>(fDataStream); 127 return file != NULL && file->InitCheck() != B_OK; 128 } 129 130 131 void 132 Transport::SetLastError(const char *e) 133 { 134 fLastErrorString = e; 135 fAbort = true; 136 } 137 138 139 void 140 Transport::Write(const void* buffer, size_t size) throw(TransportException) 141 { 142 if (fDataStream) { 143 if (size == (size_t)fDataStream->Write(buffer, size)) { 144 return; 145 } 146 SetLastError("BDataIO::Write failed."); 147 } 148 throw TransportException(LastError()); 149 } 150 151 152 void 153 Transport::Read(void* buffer, size_t size) throw(TransportException) 154 { 155 if (fDataStream) { 156 if (size == (size_t)fDataStream->Read(buffer, size)) { 157 return; 158 } 159 SetLastError("BDataIO::Read failed."); 160 } 161 throw TransportException(LastError()); 162 } 163