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_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 96Transport::~Transport() 97{ 98 if (fExitTransport) { 99 (*fExitTransport)(); 100 } 101 if (fImage >= 0) { 102 unload_add_on(fImage); 103 } 104} 105 106 107bool 108Transport::CheckAbort() const 109{ 110 return fDataStream == 0; 111} 112 113 114const 115string &Transport::LastError() const 116{ 117 return fLastErrorString; 118} 119 120 121bool 122Transport::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 131void 132Transport::SetLastError(const char *e) 133{ 134 fLastErrorString = e; 135 fAbort = true; 136} 137 138 139void 140Transport::Write(const void* buffer, size_t size) 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 152void 153Transport::Read(void* buffer, size_t size) 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