xref: /haiku/src/add-ons/input_server/devices/wacom/DeviceReader.cpp (revision e6b30aee0fd7a23d6a6baab9f3718945a0cd838a)
1 /*
2  * Copyright 2005-2008 Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
3  * Distributed under the terms of the MIT license.
4  */
5 #include "DeviceReader.h"
6 
7 #include <malloc.h>
8 #include <string.h>
9 
10 #include <File.h>
11 
12 
13 // constructor
14 DeviceReader::DeviceReader()
15 	: fDevicePath(NULL),
16 	  fDeviceFile(NULL),
17 	  fVendorID(0),
18 	  fProductID(0),
19 	  fMaxPackedSize(0)
20 {
21 }
22 
23 // destructor
24 DeviceReader::~DeviceReader()
25 {
26 	_Unset();
27 }
28 
29 // SetTo
30 status_t
31 DeviceReader::SetTo(const char* path)
32 {
33 	status_t ret = B_BAD_VALUE;
34 	if (path) {
35 		_Unset();
36 		fDevicePath = strdup(path);
37 		fDeviceFile = new BFile(path, B_READ_ONLY);
38 		ret = fDeviceFile->InitCheck();
39 		if (ret >= B_OK) {
40 			// read 8 bytes from the file and initialize
41 			// the rest of the object variables
42 			uint8 buffer[8];
43 			ret = fDeviceFile->Read(buffer, 8);
44 			if (ret == 8) {
45 				ret = B_OK;
46 				uint16* ids = (uint16*)buffer;
47 				fVendorID = ids[0];
48 				fProductID = ids[1];
49 				uint32* ps = (uint32*)buffer;
50 				fMaxPackedSize = ps[1];
51 			} else {
52 				_Unset();
53 			}
54 		}
55 	}
56 	return ret;
57 }
58 
59 // InitCheck
60 status_t
61 DeviceReader::InitCheck() const
62 {
63 	return fDeviceFile && fDevicePath ? fDeviceFile->InitCheck() : B_NO_INIT;
64 }
65 
66 // DevicePath
67 const char*
68 DeviceReader::DevicePath() const
69 {
70 	return fDevicePath;
71 }
72 
73 // DeviceFile
74 BFile*
75 DeviceReader::DeviceFile() const
76 {
77 	return fDeviceFile;
78 }
79 
80 // VendorID
81 uint16
82 DeviceReader::VendorID() const
83 {
84 	return fVendorID;
85 }
86 
87 // ProductID
88 uint16
89 DeviceReader::ProductID() const
90 {
91 	return fProductID;
92 }
93 
94 // MaxPacketSize
95 size_t
96 DeviceReader::MaxPacketSize() const
97 {
98 	return fMaxPackedSize;
99 }
100 
101 // ReadData
102 status_t
103 DeviceReader::ReadData(uint8* data, size_t size) const
104 {
105 	status_t ret = B_NO_INIT;
106 	if (fDeviceFile) {
107 		ret = fDeviceFile->InitCheck();
108 		if (ret >= B_OK) {
109 			uint8* buffer = new uint8[fMaxPackedSize + 8];
110 			ret = fDeviceFile->Read(buffer, fMaxPackedSize + 8);
111 			if (ret == (ssize_t)(fMaxPackedSize + 8)) {
112 				// make sure we don't copy too many bytes
113 				size_t length = min_c(size, fMaxPackedSize);
114 				memcpy(data, buffer + 8, length);
115 				// zero out any remaining bytes
116 				if (size > fMaxPackedSize)
117 					memset(data + length, 0, size - fMaxPackedSize);
118 				// operation could be considered successful
119 				ret = length;
120 			} else if (ret == 8 || ret == B_TIMED_OUT) {
121 				// it's ok if the operation timed out
122 				memset(data, 0, size);
123 				ret = B_OK;
124 			}
125 			delete[] buffer;
126 		}
127 	}
128 	return ret;
129 }
130 
131 // _Unset
132 void
133 DeviceReader::_Unset()
134 {
135 	free(fDevicePath);
136 	fDevicePath = NULL;
137 	delete fDeviceFile;
138 	fDeviceFile = NULL;
139 	fVendorID = 0;
140 	fProductID = 0;
141 	fMaxPackedSize = 0;
142 }
143