2 * Copyright 2001-2005, Haiku.
3 * Distributed under the terms of the MIT License.
6 * Marc Flerackers (mflerackers@androme.be)
10 #include <ByteOrder.h>
13 #include <PropertyInfo.h>
20 BPropertyInfo::BPropertyInfo(property_info
* propertyInfo
, value_info
* valueInfo
,
23 fPropInfo(propertyInfo
),
24 fValueInfo(valueInfo
),
26 fInHeap(freeOnDelete
),
29 if (fPropInfo
!= NULL
) {
30 while (fPropInfo
[fPropCount
].name
)
34 if (fValueInfo
!= NULL
) {
35 while (fValueInfo
[fValueCount
].name
)
41 BPropertyInfo::~BPropertyInfo()
47 int32
BPropertyInfo::FindMatch(BMessage
* message
, int32 index
,
48 BMessage
* specifier
, int32 form
, const char* property
, void* data
) const
50 int32 propertyIndex
= 0;
52 while (fPropInfo
!= NULL
&& fPropInfo
[propertyIndex
].name
!= NULL
) {
53 property_info
* propertyInfo
= fPropInfo
+ propertyIndex
;
55 if (!strcmp(propertyInfo
->name
, property
)
56 && FindCommand(message
->what
, index
, propertyInfo
)
57 && FindSpecifier(form
, propertyInfo
)) {
59 *((uint32
*)data
) = propertyInfo
->extra_data
;
71 BPropertyInfo::IsFixedSize() const
78 BPropertyInfo::TypeCode() const
80 return B_PROPERTY_INFO_TYPE
;
85 BPropertyInfo::FlattenedSize() const
87 size_t size
= (2 * sizeof(int32
)) + 1;
91 for (int32 pi
= 0; fPropInfo
[pi
].name
!= NULL
; pi
++) {
92 size
+= strlen(fPropInfo
[pi
].name
) + 1;
94 if (fPropInfo
[pi
].usage
)
95 size
+= strlen(fPropInfo
[pi
].usage
) + 1;
99 size
+= sizeof(int32
);
101 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].commands
[i
] != 0; i
++)
102 size
+= sizeof(int32
);
103 size
+= sizeof(int32
);
105 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].specifiers
[i
] != 0; i
++)
106 size
+= sizeof(int32
);
107 size
+= sizeof(int32
);
111 for (int32 pi
= 0; fPropInfo
[pi
].name
!= NULL
; pi
++) {
112 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].types
[i
] != 0; i
++)
113 size
+= sizeof(int32
);
114 size
+= sizeof(int32
);
116 for (int32 i
= 0; i
< 3 && fPropInfo
[pi
].ctypes
[i
].pairs
[0].name
!= 0; i
++) {
117 for (int32 j
= 0; j
< 5 && fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
!= 0; j
++) {
118 size
+= strlen(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
) + 1;
119 size
+= sizeof(int32
);
121 size
+= sizeof(int32
);
123 size
+= sizeof(int32
);
128 size
+= sizeof(int16
);
131 for (int32 vi
= 0; fValueInfo
[vi
].name
!= NULL
; vi
++) {
132 size
+= sizeof(int32
);
133 size
+= sizeof(int32
);
135 size
+= strlen(fValueInfo
[vi
].name
) + 1;
137 if (fValueInfo
[vi
].usage
)
138 size
+= strlen(fValueInfo
[vi
].usage
) + 1;
140 size
+= sizeof(char);
142 size
+= sizeof(int32
);
151 BPropertyInfo::Flatten(void* buffer
, ssize_t numBytes
) const
153 if (numBytes
< FlattenedSize())
159 BMemoryIO
flatData(buffer
, numBytes
);
161 char tmpChar
= B_HOST_IS_BENDIAN
;
164 flatData
.Write(&tmpChar
, sizeof(tmpChar
));
165 flatData
.Write(&fPropCount
, sizeof(fPropCount
));
166 tmpInt
= 0x01 | (fValueInfo
? 0x2 : 0x0);
167 flatData
.Write(&tmpInt
, sizeof(tmpInt
));
171 for (int32 pi
= 0; fPropInfo
[pi
].name
!= NULL
; pi
++) {
172 flatData
.Write(fPropInfo
[pi
].name
, strlen(fPropInfo
[pi
].name
) + 1);
173 if (fPropInfo
[pi
].usage
!= NULL
) {
174 flatData
.Write(fPropInfo
[pi
].usage
, strlen(fPropInfo
[pi
].usage
) + 1);
177 flatData
.Write(&tmpChar
, sizeof(tmpChar
));
180 flatData
.Write(&fPropInfo
[pi
].extra_data
, sizeof(fPropInfo
[pi
].extra_data
));
182 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].commands
[i
] != 0; i
++) {
183 flatData
.Write(&fPropInfo
[pi
].commands
[i
], sizeof(fPropInfo
[pi
].commands
[i
]));
186 flatData
.Write(&tmpInt
, sizeof(tmpInt
));
188 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].specifiers
[i
] != 0; i
++) {
189 flatData
.Write(&fPropInfo
[pi
].specifiers
[i
], sizeof(fPropInfo
[pi
].specifiers
[i
]));
192 flatData
.Write(&tmpInt
, sizeof(tmpInt
));
196 for (int32 pi
= 0; fPropInfo
[pi
].name
!= NULL
; pi
++) {
197 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].types
[i
] != 0; i
++) {
198 flatData
.Write(&fPropInfo
[pi
].types
[i
], sizeof(fPropInfo
[pi
].types
[i
]));
201 flatData
.Write(&tmpInt
, sizeof(tmpInt
));
203 for (int32 i
= 0; i
< 3 && fPropInfo
[pi
].ctypes
[i
].pairs
[0].name
!= 0; i
++) {
204 for (int32 j
= 0; j
< 5 && fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
!= 0; j
++) {
205 flatData
.Write(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
,
206 strlen(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
) + 1);
207 flatData
.Write(&fPropInfo
[pi
].ctypes
[i
].pairs
[j
].type
,
208 sizeof(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].type
));
211 flatData
.Write(&tmpInt
, sizeof(tmpInt
));
214 flatData
.Write(&tmpInt
, sizeof(tmpInt
));
220 flatData
.Write(&fValueCount
, sizeof(fValueCount
));
221 for (int32 vi
= 0; fValueInfo
[vi
].name
!= NULL
; vi
++) {
222 flatData
.Write(&fValueInfo
[vi
].kind
, sizeof(fValueInfo
[vi
].kind
));
223 flatData
.Write(&fValueInfo
[vi
].value
, sizeof(fValueInfo
[vi
].value
));
224 flatData
.Write(fValueInfo
[vi
].name
, strlen(fValueInfo
[vi
].name
) + 1);
225 if (fValueInfo
[vi
].usage
) {
226 flatData
.Write(fValueInfo
[vi
].usage
, strlen(fValueInfo
[vi
].usage
) + 1);
229 flatData
.Write(&tmpChar
, sizeof(tmpChar
));
231 flatData
.Write(&fValueInfo
[vi
].extra_data
, sizeof(fValueInfo
[vi
].extra_data
));
240 BPropertyInfo::AllowsTypeCode(type_code code
) const
242 return code
== B_PROPERTY_INFO_TYPE
;
247 BPropertyInfo::Unflatten(type_code code
, const void* buffer
,
250 if (!AllowsTypeCode(code
))
258 BMemoryIO
flatData(buffer
, numBytes
);
259 char tmpChar
= B_HOST_IS_BENDIAN
;
262 flatData
.Read(&tmpChar
, sizeof(tmpChar
));
263 bool swapRequired
= (tmpChar
!= B_HOST_IS_BENDIAN
);
265 flatData
.Read(&fPropCount
, sizeof(fPropCount
));
268 flatData
.Read(&flags
, sizeof(flags
));
270 fPropCount
= B_SWAP_INT32(fPropCount
);
271 flags
= B_SWAP_INT32(flags
);
275 fPropInfo
= static_cast<property_info
*>(malloc(sizeof(property_info
) * (fPropCount
+ 1)));
276 memset(fPropInfo
, 0, (fPropCount
+ 1) * sizeof(property_info
));
279 for (int32 pi
= 0; pi
< fPropCount
; pi
++) {
280 fPropInfo
[pi
].name
= strdup(static_cast<const char*>(buffer
) + flatData
.Position());
281 flatData
.Seek(strlen(fPropInfo
[pi
].name
) + 1, SEEK_CUR
);
283 fPropInfo
[pi
].usage
= strdup(static_cast<const char *>(buffer
) + flatData
.Position());
284 flatData
.Seek(strlen(fPropInfo
[pi
].usage
) + 1, SEEK_CUR
);
286 flatData
.Read(&fPropInfo
[pi
].extra_data
, sizeof(fPropInfo
[pi
].extra_data
));
288 fPropInfo
[pi
].extra_data
= B_SWAP_INT32(fPropInfo
[pi
].extra_data
);
291 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
292 for (int32 i
= 0; tmpInt
!= 0; i
++) {
294 tmpInt
= B_SWAP_INT32(tmpInt
);
296 fPropInfo
[pi
].commands
[i
] = tmpInt
;
297 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
300 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
301 for (int32 i
= 0; tmpInt
!= 0; i
++) {
303 tmpInt
= B_SWAP_INT32(tmpInt
);
305 fPropInfo
[pi
].specifiers
[i
] = tmpInt
;
306 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
311 for (int32 pi
= 0; pi
< fPropCount
; pi
++) {
312 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
313 for (int32 i
= 0; tmpInt
!= 0; i
++) {
315 tmpInt
= B_SWAP_INT32(tmpInt
);
317 fPropInfo
[pi
].types
[i
] = tmpInt
;
318 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
321 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
322 for (int32 i
= 0; tmpInt
!= 0; i
++) {
323 for (int32 j
= 0; tmpInt
!= 0; j
++) {
324 flatData
.Seek(-sizeof(tmpInt
), SEEK_CUR
);
325 fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
=
326 strdup(static_cast<const char *>(buffer
) + flatData
.Position());
327 flatData
.Seek(strlen(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].name
) + 1, SEEK_CUR
);
329 flatData
.Read(&fPropInfo
[pi
].ctypes
[i
].pairs
[j
].type
,
330 sizeof(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].type
));
332 fPropInfo
[pi
].ctypes
[i
].pairs
[j
].type
=
333 B_SWAP_INT32(fPropInfo
[pi
].ctypes
[i
].pairs
[j
].type
);
335 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
337 flatData
.Read(&tmpInt
, sizeof(tmpInt
));
343 flatData
.Read(&fValueCount
, sizeof(fValueCount
));
345 fValueCount
= B_SWAP_INT16(fValueCount
);
348 fValueInfo
= static_cast<value_info
*>(malloc(sizeof(value_info
) * (fValueCount
+ 1)));
349 memset(fValueInfo
, 0, (fValueCount
+ 1) * sizeof(value_info
));
351 for (int32 vi
= 0; vi
< fValueCount
; vi
++) {
352 flatData
.Read(&fValueInfo
[vi
].kind
, sizeof(fValueInfo
[vi
].kind
));
353 flatData
.Read(&fValueInfo
[vi
].value
, sizeof(fValueInfo
[vi
].value
));
355 fValueInfo
[vi
].name
= strdup(static_cast<const char *>(buffer
) + flatData
.Position());
356 flatData
.Seek(strlen(fValueInfo
[vi
].name
) + 1, SEEK_CUR
);
358 fValueInfo
[vi
].usage
= strdup(static_cast<const char *>(buffer
) + flatData
.Position());
359 flatData
.Seek(strlen(fValueInfo
[vi
].usage
) + 1, SEEK_CUR
);
361 flatData
.Read(&fValueInfo
[vi
].extra_data
, sizeof(fValueInfo
[vi
].extra_data
));
363 fValueInfo
[vi
].kind
= static_cast<value_kind
>(B_SWAP_INT32(fValueInfo
[vi
].kind
));
364 fValueInfo
[vi
].value
= B_SWAP_INT32(fValueInfo
[vi
].value
);
365 fValueInfo
[vi
].extra_data
= B_SWAP_INT32(fValueInfo
[vi
].extra_data
);
375 BPropertyInfo::Properties() const
382 BPropertyInfo::Values() const
389 BPropertyInfo::CountProperties() const
396 BPropertyInfo::CountValues() const
403 BPropertyInfo::PrintToStream() const
405 printf(" property commands types specifiers\n");
406 printf("--------------------------------------------------------------------------------\n");
408 for (int32 pi
= 0; fPropInfo
[pi
].name
!= 0; pi
++) {
410 printf("%14s", fPropInfo
[pi
].name
);
412 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].commands
[i
] != 0; i
++) {
413 uint32 command
= fPropInfo
[pi
].commands
[i
];
415 printf(" %c%c%c%-28c", int(command
& 0xFF000000) >> 24,
416 int(command
& 0xFF0000) >> 16, int(command
& 0xFF00) >> 8,
417 int(command
) & 0xFF);
420 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].types
[i
] != 0; i
++) {
421 uint32 type
= fPropInfo
[pi
].types
[i
];
423 printf("%c%c%c%c", int(type
& 0xFF000000) >> 24,
424 int(type
& 0xFF0000) >> 16, int(type
& 0xFF00) >> 8, (int)type
& 0xFF);
427 for (int32 i
= 0; i
< 10 && fPropInfo
[pi
].specifiers
[i
] != 0; i
++) {
428 uint32 spec
= fPropInfo
[pi
].specifiers
[i
];
429 printf("%" B_PRIu32
, spec
);
437 BPropertyInfo::FindCommand(uint32 what
, int32 index
, property_info
*propertyInfo
)
441 if (propertyInfo
->commands
[0] == 0) {
443 } else if (index
== 0) {
444 for (int32 i
= 0; i
< 10 && propertyInfo
->commands
[i
] != 0; i
++) {
445 if (propertyInfo
->commands
[i
] == what
) {
457 BPropertyInfo::FindSpecifier(uint32 form
, property_info
*propertyInfo
)
461 if (propertyInfo
->specifiers
[0] == 0) {
464 for (int32 i
= 0; i
< 10 && propertyInfo
->specifiers
[i
] != 0; i
++) {
465 if (propertyInfo
->specifiers
[i
] == form
) {
476 void BPropertyInfo::_ReservedPropertyInfo1() {}
477 void BPropertyInfo::_ReservedPropertyInfo2() {}
478 void BPropertyInfo::_ReservedPropertyInfo3() {}
479 void BPropertyInfo::_ReservedPropertyInfo4() {}
482 BPropertyInfo::BPropertyInfo(const BPropertyInfo
&)
488 BPropertyInfo::operator=(const BPropertyInfo
&)
495 BPropertyInfo::FreeMem()
502 if (fPropInfo
!= NULL
) {
503 for (i
= 0; i
< fPropCount
; i
++) {
504 free((char *)fPropInfo
[i
].name
);
505 free((char *)fPropInfo
[i
].usage
);
507 for (j
= 0; j
< 3; j
++) {
508 for (k
= 0; k
< 5; k
++) {
509 if (fPropInfo
[i
].ctypes
[j
].pairs
[k
].name
== NULL
)
512 free((char *)fPropInfo
[i
].ctypes
[j
].pairs
[k
].name
);
515 if (fPropInfo
[i
].ctypes
[j
].pairs
[0].name
== NULL
)
524 if (fValueInfo
!= NULL
) {
525 for (i
= 0; i
< fValueCount
; i
++) {
526 free((char *)fValueInfo
[i
].name
);
527 free((char *)fValueInfo
[i
].usage
);