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