1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30of Be Incorporated in the United States and other countries. Other brand product
31names are registered trademarks or trademarks of their respective holders.
32All rights reserved.
33*/
34
35//	attribute streams allow copying/filtering/transformation of attributes
36//	between file and/or memory nodes
37//
38//	for example one can use constructs of nodes like:
39//
40// 	destinationNode << transformer << buffer << filter << sourceNode
41//
42//	transformer may for instance perform endian-swapping or offsetting of
43//	a B_RECT attribute filter may withold certain attributes buffer is a
44//	memory allocated snapshot of attributes, may be repeatedly streamed into
45//	other files, buffers
46//
47//	In addition to the whacky (but usefull) << syntax, calls like Read, Write
48//	are also available
49#ifndef _ATTRIBUTE_STREAM_H
50#define _ATTRIBUTE_STREAM_H
51
52
53#include <ObjectList.h>
54#include <Node.h>
55#include <Rect.h>
56#include <String.h>
57#include <TypeConstants.h>
58
59#include <fs_attr.h>
60
61
62namespace BPrivate {
63
64struct AttributeTemplate {
65	// used for read-only attribute source
66	const char* fAttributeName;
67	uint32 fAttributeType;
68	off_t fSize;
69	const char* fBits;
70};
71
72
73class AttributeInfo {
74	// utility class for internal attribute description
75public:
76	AttributeInfo();
77	AttributeInfo(const AttributeInfo& other);
78	AttributeInfo(const char* name, attr_info info);
79	AttributeInfo(const char* name, uint32 type, off_t size);
80
81	void SetTo(const AttributeInfo& other);
82	void SetTo(const char* name, attr_info info);
83	void SetTo(const char* name, uint32 type, off_t size);
84	const char* Name() const;
85	uint32 Type() const;
86	off_t Size() const;
87
88private:
89	BString fName;
90	attr_info fInfo;
91};
92
93
94class AttributeStreamNode {
95public:
96	AttributeStreamNode();
97	virtual ~AttributeStreamNode();
98
99	AttributeStreamNode &operator<<(AttributeStreamNode &source);
100		// workhorse call
101		// to the outside makes this node a part of the stream, passing on
102		// any data it has, gets, transforms, doesn't filter out
103		//
104		// under the hood sets up streaming into the next node; hooking
105		// up source and destination, forces the stream head to start
106		// streaming
107
108	virtual void Rewind();
109		// get ready to start all over again
110	virtual void MakeEmpty() {}
111		// remove any attributes the node may have
112
113	virtual off_t Contains(const char*, uint32);
114		// returns size of attribute if found
115
116	virtual off_t Read(const char* name, const char* foreignName,
117		uint32 type, off_t size, void* buffer, void (*swapFunc)(void*) = 0);
118		// read from this node
119	virtual off_t Write(const char* name, const char* foreignName,
120		uint32 type, off_t size, const void* buffer);
121		// write to this node
122
123	// work calls
124	virtual bool Drive();
125		// node at the head of the stream makes the entire stream
126		// feed it
127	virtual const AttributeInfo* Next();
128		// give me the next attribute in the stream
129	virtual const char* Get();
130		// give me the data of the attribute in the stream that was just
131		// returned by Next assumes there is a buffering node somewhere on the
132		// way to the source, from which the resulting buffer is borrowed
133	virtual bool Fill(char* buffer) const;
134		// fill the buffer with data of the attribute in the stream that was
135		// just returned by next <buffer> is big enough to hold the entire
136		// attribute data
137
138	virtual bool CanFeed() const { return false; }
139		// return true if can work as a source for the entire stream
140
141private:
142	bool Start();
143		// utility call, used to start up the stream by finding the ultimate
144		// target of the stream and calling Drive on it
145
146	void Detach();
147
148protected:
149	AttributeStreamNode* fReadFrom;
150	AttributeStreamNode* fWriteTo;
151};
152
153
154class AttributeStreamFileNode : public AttributeStreamNode {
155	// handles reading and writing attributes to and from the
156	// stream
157public:
158	AttributeStreamFileNode();
159	AttributeStreamFileNode(BNode*);
160
161	virtual void MakeEmpty();
162	virtual void Rewind();
163	virtual off_t Contains(const char* name, uint32 type);
164	virtual off_t Read(const char* name, const char* foreignName, uint32 type,
165		off_t size, void* buffer, void (*swapFunc)(void*) = 0);
166	virtual off_t Write(const char* name, const char* foreignName, uint32 type,
167		off_t size, const void* buffer);
168
169	void SetTo(BNode*);
170
171	BNode* Node() { return fNode; }
172
173protected:
174	virtual bool CanFeed() const { return true; }
175
176	virtual bool Drive();
177		// give me all the attributes, I'll write them into myself
178	virtual const AttributeInfo* Next();
179		// return the info for the next attribute I can read for you
180	virtual const char* Get();
181	virtual bool Fill(char* buffer) const;
182
183private:
184	AttributeInfo fCurrentAttr;
185	BNode* fNode;
186
187	typedef AttributeStreamNode _inherited;
188};
189
190
191class AttributeStreamMemoryNode : public AttributeStreamNode {
192	// in memory attribute buffer; can be both target of writing and source
193	// of reading at the same time
194public:
195	AttributeStreamMemoryNode();
196
197	virtual void MakeEmpty();
198	virtual off_t Contains(const char* name, uint32 type);
199	virtual off_t Read(const char* name, const char* foreignName,
200		uint32 type, off_t size, void* buffer, void (*swapFunc)(void*) = 0);
201	virtual off_t Write(const char* name, const char* foreignName,
202		uint32 type, off_t size, const void* buffer);
203
204protected:
205	virtual bool CanFeed() const { return true; }
206	virtual void Rewind();
207	virtual bool Drive();
208	virtual const AttributeInfo* Next();
209	virtual const char* Get();
210	virtual bool Fill(char* buffer) const;
211
212	class AttrNode {
213	public:
214		AttrNode(const char* name, uint32 type, off_t size, char* data)
215		:
216		fAttr(name, type, size),
217		fData(data)
218		{
219		}
220
221		~AttrNode()
222		{
223			delete[] fData;
224		}
225
226		AttributeInfo fAttr;
227		char* fData;
228	};
229
230		// utility calls
231	virtual AttrNode* BufferingGet();
232	virtual AttrNode* BufferingGet(const char* name, uint32 type, off_t size);
233	int32 Find(const char* name, uint32 type) const;
234
235private:
236	BObjectList<AttrNode> fAttributes;
237	int32 fCurrentIndex;
238
239	typedef AttributeStreamNode _inherited;
240};
241
242
243class AttributeStreamTemplateNode : public AttributeStreamNode {
244	// in read-only memory attribute source
245	// can only be used as a source for Next and Get
246public:
247	AttributeStreamTemplateNode(const AttributeTemplate*, int32 count);
248
249	virtual off_t Contains(const char* name, uint32 type);
250
251protected:
252	virtual bool CanFeed() const { return true; }
253	virtual void Rewind();
254	virtual const AttributeInfo* Next();
255	virtual const char* Get();
256	virtual bool Fill(char* buffer) const;
257
258	int32 Find(const char* name, uint32 type) const;
259
260private:
261	AttributeInfo fCurrentAttr;
262	const AttributeTemplate* fAttributes;
263	int32 fCurrentIndex;
264	int32 fCount;
265
266	typedef AttributeStreamNode _inherited;
267};
268
269
270class AttributeStreamFilterNode : public AttributeStreamNode {
271	// filter node may not pass thru specified attributes
272public:
273	AttributeStreamFilterNode()
274		{}
275	virtual off_t Contains(const char* name, uint32 type);
276	virtual off_t Read(const char* name, const char* foreignName,
277		uint32 type, off_t size, void* buffer, void (*swapFunc)(void*) = 0);
278	virtual off_t Write(const char* name, const char* foreignName,
279		uint32 type, off_t size, const void* buffer);
280
281protected:
282	virtual bool Reject(const char* name, uint32 type, off_t size);
283		// override to implement filtering
284	virtual const AttributeInfo* Next();
285
286private:
287	typedef AttributeStreamNode _inherited;
288};
289
290
291class NamesToAcceptAttrFilter : public AttributeStreamFilterNode {
292	// filter node that only passes thru attributes that match
293	// a list of names
294public:
295	NamesToAcceptAttrFilter(const char**);
296
297protected:
298	virtual bool Reject(const char* name, uint32 type, off_t size);
299
300private:
301	const char** fNameList;
302};
303
304
305class SelectiveAttributeTransformer : public AttributeStreamNode {
306	// node applies a transformation on specified attributes
307public:
308	SelectiveAttributeTransformer(const char* attributeName,
309		bool (*)(const char*, uint32 , off_t , void*, void*), void* params);
310	virtual ~SelectiveAttributeTransformer();
311
312	virtual off_t Read(const char* name, const char* foreignName, uint32 type,
313		off_t size, void* buffer, void (*swapFunc)(void*) = 0);
314
315	virtual void Rewind();
316
317protected:
318	virtual bool WillTransform(const char* name, uint32 type, off_t size,
319		const char* data) const;
320		// override to implement filtering, should only return true if
321		// transformation will occur
322	virtual char* CopyAndApplyTransformer(const char* name, uint32 type,
323		off_t size, const char* data);
324		// makes a copy of data
325	virtual bool ApplyTransformer(const char* name, uint32 type, off_t size,
326		char* data);
327		// transforms in place
328	virtual const AttributeInfo* Next();
329	virtual const char* Get();
330
331private:
332	AttributeInfo fCurrentAttr;
333	const char* fAttributeNameToTransform;
334	bool (*fTransformFunc)(const char*, uint32 , off_t , void*, void*);
335	void* fTransformParams;
336
337	BObjectList<char> fTransformedBuffers;
338
339	typedef AttributeStreamNode _inherited;
340};
341
342
343template <class Type>
344class AttributeStreamConstValue : public AttributeStreamNode {
345public:
346	AttributeStreamConstValue(const char* name, uint32 attributeType,
347		Type value);
348
349protected:
350	virtual bool CanFeed() const { return true; }
351	virtual void Rewind() { fRewound = true; }
352	virtual const AttributeInfo* Next();
353	virtual const char* Get();
354	virtual bool Fill(char* buffer) const;
355
356	int32 Find(const char* name, uint32 type) const;
357
358private:
359	AttributeInfo fAttr;
360	Type fValue;
361	bool fRewound;
362
363	typedef AttributeStreamNode _inherited;
364};
365
366
367template<class Type>
368AttributeStreamConstValue<Type>::AttributeStreamConstValue(const char* name,
369	uint32 attributeType, Type value)
370	:
371	fAttr(name, attributeType, sizeof(Type)),
372	fValue(value),
373	fRewound(true)
374{
375}
376
377
378template<class Type>
379const AttributeInfo*
380AttributeStreamConstValue<Type>::Next()
381{
382	if (!fRewound)
383		return NULL;
384
385	fRewound = false;
386	return &fAttr;
387}
388
389
390template<class Type>
391const char*
392AttributeStreamConstValue<Type>::Get()
393{
394	return (const char*)&fValue;
395}
396
397
398template<class Type>
399bool
400AttributeStreamConstValue<Type>::Fill(char* buffer) const
401{
402	memcpy(buffer, &fValue, sizeof(Type));
403	return true;
404}
405
406
407template<class Type>
408int32
409AttributeStreamConstValue<Type>::Find(const char* name, uint32 type) const
410{
411	if (strcmp(fAttr.Name(), name) == 0 && type == fAttr.Type())
412		return 0;
413
414	return -1;
415}
416
417
418class AttributeStreamBoolValue : public AttributeStreamConstValue<bool> {
419public:
420	AttributeStreamBoolValue(const char* name, bool value)
421		:
422		AttributeStreamConstValue<bool>(name, B_BOOL_TYPE, value)
423	{
424	}
425};
426
427
428class AttributeStreamInt32Value : public AttributeStreamConstValue<int32> {
429public:
430	AttributeStreamInt32Value(const char* name, int32 value)
431		:
432		AttributeStreamConstValue<int32>(name, B_INT32_TYPE, value)
433	{
434	}
435};
436
437
438class AttributeStreamInt64Value : public AttributeStreamConstValue<int64> {
439public:
440	AttributeStreamInt64Value(const char* name, int64 value)
441		:
442		AttributeStreamConstValue<int64>(name, B_INT64_TYPE, value)
443	{
444	}
445};
446
447
448class AttributeStreamRectValue : public AttributeStreamConstValue<BRect> {
449public:
450	AttributeStreamRectValue(const char* name, BRect value)
451		:
452		AttributeStreamConstValue<BRect>(name, B_RECT_TYPE, value)
453	{
454	}
455};
456
457
458class AttributeStreamFloatValue : public AttributeStreamConstValue<float> {
459public:
460	AttributeStreamFloatValue(const char* name, float value)
461		:
462		AttributeStreamConstValue<float>(name, B_FLOAT_TYPE, value)
463	{
464	}
465};
466
467} // namespace BPrivate
468
469using namespace BPrivate;
470
471
472#endif	// _ATTRIBUTE_STREAM_H
473