xref: /haiku/src/libs/print/libprint/Transport.cpp (revision 239222b2369c39dc52df52b0a7cdd6cc0a91bc92)
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 #if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE))
19 using namespace std;
20 #else
21 #define std
22 #endif
23 
24 Transport::Transport(const PrinterData *printer_data)
25 	: fImage(-1), fInitTransport(0), fExitTransport(0), fDataStream(0), fAbort(false)
26 {
27 	BPath path;
28 
29 	if (B_OK == find_directory(B_USER_ADDONS_DIRECTORY, &path)) {
30 		path.Append("Print/transport");
31 		path.Append(printer_data->getTransport().c_str());
32 		DBGMSG(("load_add_on: %s\n", path.Path()));
33 		fImage = load_add_on(path.Path());
34 	}
35 	if (fImage < 0) {
36 		if (B_OK == find_directory(B_BEOS_ADDONS_DIRECTORY, &path)) {
37 			path.Append("Print/transport");
38 			path.Append(printer_data->getTransport().c_str());
39 			DBGMSG(("load_add_on: %s\n", path.Path()));
40 			fImage = load_add_on(path.Path());
41 		}
42 	}
43 
44 	if (fImage < 0) {
45 		set_last_error("cannot load a transport add-on");
46 		return;
47 	}
48 
49 	DBGMSG(("image id = %d\n", (int)fImage));
50 
51 	get_image_symbol(fImage, "init_transport", B_SYMBOL_TYPE_TEXT, (void **)&fInitTransport);
52 	get_image_symbol(fImage, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **)&fExitTransport);
53 
54 	if (fInitTransport == NULL) {
55 		set_last_error("get_image_symbol failed.");
56 		DBGMSG(("init_transport is NULL\n"));
57 	}
58 
59 	if (fExitTransport == NULL) {
60 		set_last_error("get_image_symbol failed.");
61 		DBGMSG(("exit_transport is NULL\n"));
62 	}
63 
64 	if (fInitTransport) {
65 		string spool_path;
66 		printer_data->getPath(spool_path);
67 		BMessage *msg = new BMessage('TRIN');
68 		msg->AddString("printer_file", spool_path.c_str());
69 		fDataStream = (*fInitTransport)(msg);
70 		delete msg;
71 		if (fDataStream == 0) {
72 			set_last_error("init_transport failed.");
73 		}
74 	}
75 }
76 
77 Transport::~Transport()
78 {
79 	if (fExitTransport) {
80 		(*fExitTransport)();
81 	}
82 	if (fImage >= 0) {
83 		unload_add_on(fImage);
84 	}
85 }
86 
87 bool Transport::check_abort() const
88 {
89 	return fDataStream == 0;
90 }
91 
92 const string &Transport::last_error() const
93 {
94 	return fLastErrorString;
95 }
96 
97 bool Transport::is_print_to_file_canceled() const
98 {
99 	// The BeOS "Print To File" transport add-on returns a non-NULL BDataIO *
100 	// even after user filepanel cancellation!
101 	BFile* file = dynamic_cast<BFile*>(fDataStream);
102 	return file != NULL && file->InitCheck() != B_OK;
103 }
104 
105 void Transport::set_last_error(const char *e)
106 {
107 	fLastErrorString = e;
108 	fAbort = true;
109 }
110 
111 void Transport::write(const void *buffer, size_t size) throw(TransportException)
112 {
113 	if (fDataStream) {
114 		if (size == (size_t)fDataStream->Write(buffer, size)) {
115 			return;
116 		}
117 		set_last_error("BDataIO::Write failed.");
118 	}
119 	throw TransportException(last_error());
120 }
121