1/*
2 * Copyright 2002-2012, Haiku. All Rights Reserved.
3 * This file may be used under the terms of the MIT License.
4 *
5 * Author: Zousar Shaker
6 *         Axel D��rfler, axeld@pinc-software.de
7 *         Marcus Overhagen
8 */
9
10
11/*! Implements the following classes:
12	BParameterWeb, BParameterGroup, BParameter, BNullParameter,
13	BContinuousParameter, BDiscreteParameter
14*/
15
16
17#include <ParameterWeb.h>
18
19#include <new>
20#include <string.h>
21
22#include <MediaNode.h>
23#include <MediaRoster.h>
24
25#include "DataExchange.h"
26#include "debug.h"
27#include "MediaMisc.h"
28
29
30/*
31	The following is documentation on the flattened format
32	of structures/classes in this module:
33
34	//--------BEGIN-CORE-BPARAMETER-STRUCT---------------------
35	?? (0x02040607): 4 bytes
36	BParameter Struct Size (in bytes): 4 bytes
37	ID: 4 bytes
38	Name String Length: 1 byte (??)
39		Name String: 'Name String Length' bytes
40	Kind String Length: 1 byte (??)
41		Kind String: 'Kind String Length' bytes
42	Unit String Length: 1 byte (??)
43		Unit String: 'Unit String Length' bytes
44	Inputs Count: 4 bytes
45		Inputs (pointers): ('Inputs Count')*4 bytes
46	Outputs Count: 4 bytes
47		Outputs (pointers): ('Outputs Count')*4 bytes
48	Media Type: 4 bytes
49	ChannelCount: 4 bytes
50	Flags: 4 bytes
51	//---------END-CORE-BPARAMETER-STRUCT-----------------------
52	//--------BEGIN-BCONTINUOUSPARAMETER-STRUCT---------
53	Min: 4 bytes (as float)
54	Max: 4 bytes (as float)
55	Stepping: 4 bytes (as float)
56	Response: 4 bytes (as int or enum)
57	Factor: 4 bytes (as float)
58	Offset: 4 bytes (as float)
59	//--------END-BCONTINUOUSPARAMETER-STRUCT-------------
60	//--------BEGIN-BDISCRETEPARAMETER-STRUCT----------------
61	NumItems: 4 bytes (as int)
62		//for each item BEGIN
63		Item Name String Length: 1 byte
64			Item Name String: 'Item Name String Length' bytes
65		Item Value: 4 bytes (as int)
66		//for each item END
67	//--------END-BDISCRETEPARAMETER-STRUCT-------------------
68
69	//--------BEGIN-CORE-BPARAMETERGROUP-STRUCT-----------
70	?? (0x03040507 OR 0x03040509 depending if the flags field is included or not???): 4 bytes
71	(possible) Flags: 4 bytes
72	Name String Length: 1 byte (??)
73		Name String: 'Name String Length' bytes
74	Param Count: 4 bytes
75		//for each Param BEGIN
76		Pointer: 4 bytes
77		Parameter Type: 4 bytes
78		Flattened Parameter Size: 4 bytes
79		Flattened Parameter: 'Flattened Parameter Size' bytes
80		//for each Param END
81	Subgroup Count: 4 bytes
82		//for each SubGroup BEGIN
83		Pointer: 4 bytes
84		MEDIA PARAMETER GROUP TYPE('BMCG' (opposite byte order in file)): 4 bytes
85		Flattened Group Size: 4 bytes
86		Flattened Group: 'Flattened Group Size' bytes
87		//for each SubGroup END
88
89	//---------END-CORE-BPARAMETERGROUP-STRUCT--------------
90
91	//--------BEGIN-CORE-BPARAMETERWEB-STRUCT-----------
92	?? 0x01030506: 4 bytes
93	??: 4 bytes (is always 1)
94	Group Count: 4 bytes
95	Node (as media_node): 0x18 bytes (decimal 24 bytes)
96		//for each Group BEGIN
97		Flattened Group Size: 4 bytes
98		Flattened Group: 'Flattened Group Size' bytes
99		//for each Group END
100		//for each Group BEGIN
101		??: 4 bytes (never get written to (holds uninitialized value))
102		//for each Group END
103	//---------END-CORE-BPARAMETERWEB-STRUCT--------------
104
105*/
106
107
108const char * const B_GENERIC			 = "";
109const char * const B_MASTER_GAIN		 = "Master";
110const char * const B_GAIN				 = "Gain";
111const char * const B_BALANCE			 = "Balance";
112const char * const B_FREQUENCY			 = "Frequency";
113const char * const B_LEVEL				 = "Level";
114const char * const B_SHUTTLE_SPEED		 = "Speed";
115const char * const B_CROSSFADE			 = "XFade";
116const char * const B_EQUALIZATION		 = "EQ";
117const char * const B_COMPRESSION		 = "Compression";
118const char * const B_QUALITY			 = "Quality";
119const char * const B_BITRATE			 = "Bitrate";
120const char * const B_GOP_SIZE			 = "GOPSize";
121const char * const B_MUTE				 = "Mute";
122const char * const B_ENABLE				 = "Enable";
123const char * const B_INPUT_MUX			 = "Input";
124const char * const B_OUTPUT_MUX			 = "Output";
125const char * const B_TUNER_CHANNEL		 = "Channel";
126const char * const B_TRACK				 = "Track";
127const char * const B_RECSTATE			 = "RecState";
128const char * const B_SHUTTLE_MODE		 = "Shuttle";
129const char * const B_RESOLUTION			 = "Resolution";
130const char * const B_COLOR_SPACE		 = "Colorspace";
131const char * const B_FRAME_RATE			 = "FrameRate";
132const char * const B_VIDEO_FORMAT		 = "VideoFormat";
133const char * const B_WEB_PHYSICAL_INPUT	 = "PhysInput";
134const char * const B_WEB_PHYSICAL_OUTPUT = "PhysOutput";
135const char * const B_WEB_ADC_CONVERTER	 = "ADC";
136const char * const B_WEB_DAC_CONVERTER	 = "DAC";
137const char * const B_WEB_LOGICAL_INPUT	 = "LogInput";
138const char * const B_WEB_LOGICAL_OUTPUT	 = "LogOutput";
139const char * const B_WEB_LOGICAL_BUS	 = "LogBus";
140const char * const B_WEB_BUFFER_INPUT	 = "DataInput";
141const char * const B_WEB_BUFFER_OUTPUT	 = "DataOutput";
142const char * const B_SIMPLE_TRANSPORT	 = "SimpleTransport";
143
144// Flattened data
145
146static const int32 kCurrentParameterWebVersion = 1;
147static const uint32 kParameterWebMagic = 0x01030506;
148static const uint32 kBufferGroupMagic = 0x03040509;
149static const uint32 kBufferGroupMagicNoFlags = 0x03040507;
150static const uint32 kParameterMagic = 0x02040607;
151
152static const ssize_t kAdditionalParameterGroupSize = 12;
153static const ssize_t kAdditionalParameterSize = 35;
154
155/* BContinuousParameter - FlattenedSize() fixed part
156 *	Min: 4 bytes (as float)
157 *	Max: 4 bytes (as float)
158 *	Stepping: 4 bytes (as float)
159 *	Response: 4 bytes (as int or enum)
160 *	Factor: 4 bytes (as float)
161 *	Offset: 4 bytes (as float)
162 */
163static const ssize_t kAdditionalContinuousParameterSize = 24;
164static const ssize_t kAdditionalDiscreteParameterSize = sizeof(ssize_t);
165
166
167// helper functions
168
169
170template<class Type> Type
171read_from_buffer(const void **_buffer)
172{
173	const Type *typedBuffer = static_cast<const Type *>(*_buffer);
174	Type value = *typedBuffer;
175
176	typedBuffer++;
177	*_buffer = static_cast<const void *>(typedBuffer);
178
179	return value;
180}
181
182
183static status_t
184read_string_from_buffer(const void **_buffer, char **_string, ssize_t size)
185{
186	if (size < 1)
187		return B_BAD_VALUE;
188
189	const uint8 *buffer = static_cast<const uint8 *>(*_buffer);
190	uint8 length = *buffer++;
191	if (length > size - 1)
192		return B_BAD_VALUE;
193
194	char *string = (char *)malloc(length + 1);
195	if (string == NULL)
196		return B_NO_MEMORY;
197
198	memcpy(string, buffer, length);
199	string[length] = '\0';
200
201	*_buffer = static_cast<const void *>(buffer + length);
202	*_string = string;
203	return B_OK;
204}
205
206
207// currently unused
208#if 0
209template<class Type> Type *
210reserve_in_buffer(void **_buffer)
211{
212	Type *typedBuffer = static_cast<Type *>(*_buffer);
213
214	*typedBuffer = 0;
215	typedBuffer++;
216
217	*_buffer = static_cast<void *>(typedBuffer);
218}
219#endif
220
221template<class Type> void
222write_to_buffer(void **_buffer, Type value)
223{
224	Type *typedBuffer = static_cast<Type *>(*_buffer);
225
226	*typedBuffer = value;
227	typedBuffer++;
228
229	*_buffer = static_cast<void *>(typedBuffer);
230}
231
232
233void
234write_string_to_buffer(void **_buffer, const char *string)
235{
236	uint8 *buffer = static_cast<uint8 *>(*_buffer);
237	uint32 length = string ? strlen(string) : 0;
238	if (length > 255)
239		length = 255;
240
241	*buffer++ = static_cast<uint8>(length);
242	if (length) {
243		memcpy(buffer, string, length);
244		buffer += length;
245	}
246
247	*_buffer = static_cast<void *>(buffer);
248}
249
250
251static void
252skip_in_buffer(const void **_buffer, uint32 bytes)
253{
254	const uint8 *buffer = static_cast<const uint8 *>(*_buffer);
255
256	buffer += bytes;
257
258	*_buffer = static_cast<const void *>(buffer);
259}
260
261
262static void inline
263skip_in_buffer(void **_buffer, uint32 bytes)
264{
265	// This actually shouldn't be necessary, but I believe it's a
266	// bug in Be's gcc - it complains about "adds cv-quals without intervening `const'"
267	// when passing a "const void **" pointer as the first argument.
268	// Maybe I am just stupid, though -- axeld.
269
270	skip_in_buffer((const void **)_buffer, bytes);
271}
272
273
274template<class Type> Type
275swap32(Type value, bool doSwap)
276{
277	STATIC_ASSERT(sizeof(Type) == 4);
278
279	if (doSwap)
280		return (Type)B_SWAP_INT32((int32)value);
281
282	return value;
283}
284
285
286template<class Type> Type
287swap64(Type value, bool doSwap)
288{
289	STATIC_ASSERT(sizeof(Type) == 8);
290
291	if (doSwap)
292		return (Type)B_SWAP_INT64((int64)value);
293
294	return value;
295}
296
297
298template<class Type> Type
299read_from_buffer_swap32(const void **_buffer, bool doSwap)
300{
301	return swap32<Type>(read_from_buffer<Type>(_buffer), doSwap);
302}
303
304
305template<class Type> Type
306read_pointer_from_buffer_swap(const void **_buffer, bool doSwap)
307{
308#if B_HAIKU_32_BIT
309	return swap32<Type>(read_from_buffer<Type>(_buffer), doSwap);
310#elif B_HAIKU_64_BIT
311	return swap64<Type>(read_from_buffer<Type>(_buffer), doSwap);
312#else
313#	error Interesting
314#endif
315}
316
317
318static inline ssize_t
319size_left(ssize_t size, const void *bufferStart, const void *buffer)
320{
321	return size - static_cast<ssize_t>((const uint8 *)buffer - (const uint8 *)bufferStart);
322}
323
324
325//	#pragma mark - BParameterWeb
326
327
328BParameterWeb::BParameterWeb()
329	:
330	fNode(media_node::null)
331		// fNode is set in BControllable::SetParameterWeb()
332{
333	CALLED();
334
335	fGroups = new BList();
336	fOldRefs = new BList();
337	fNewRefs = new BList();
338}
339
340
341BParameterWeb::~BParameterWeb()
342{
343	CALLED();
344
345	for (int32 i = fGroups->CountItems(); i-- > 0;) {
346		delete static_cast<BParameterGroup*>(fGroups->ItemAt(i));
347	}
348
349	delete fGroups;
350	delete fOldRefs;
351	delete fNewRefs;
352}
353
354
355media_node
356BParameterWeb::Node()
357{
358	return fNode;
359}
360
361
362BParameterGroup*
363BParameterWeb::MakeGroup(const char* name)
364{
365	CALLED();
366
367	BParameterGroup* group = new(std::nothrow) BParameterGroup(this, name);
368	if (group == NULL)
369		return NULL;
370
371	if (!fGroups->AddItem(group)) {
372		delete group;
373		return NULL;
374	}
375
376	return group;
377}
378
379
380int32
381BParameterWeb::CountGroups()
382{
383	return fGroups->CountItems();
384}
385
386
387BParameterGroup*
388BParameterWeb::GroupAt(int32 index)
389{
390	return static_cast<BParameterGroup*>(fGroups->ItemAt(index));
391}
392
393
394int32
395BParameterWeb::CountParameters()
396{
397	CALLED();
398
399	// Counts over all groups (and sub-groups) in the web.
400	// The "groups" list is used as count stack
401
402	BList groups(*fGroups);
403	int32 count = 0;
404
405	for (int32 i = 0; i < groups.CountItems(); i++) {
406		BParameterGroup* group
407			= static_cast<BParameterGroup*>(groups.ItemAt(i));
408
409		count += group->CountParameters();
410
411		if (group->fGroups != NULL)
412			groups.AddList(group->fGroups);
413	}
414
415	return count;
416}
417
418
419BParameter*
420BParameterWeb::ParameterAt(int32 index)
421{
422	CALLED();
423
424	// Iterates over all groups (and sub-groups) in the web.
425	// The "groups" list is used as iteration stack (breadth search style)
426	// Maintains the same order as the Be implementation
427
428	BList groups(*fGroups);
429
430	for (int32 i = 0; i < groups.CountItems(); i++) {
431		BParameterGroup* group
432			= static_cast<BParameterGroup*>(groups.ItemAt(i));
433		int32 count = group->CountParameters();
434		if (index < count)
435			return group->ParameterAt(index);
436
437		index -= count;
438			// the index is always relative to the start of the current group
439
440		if (group->fGroups != NULL)
441			groups.AddList(group->fGroups);
442	}
443
444	TRACE("*** could not find parameter at %ld (count = %ld)\n", index,
445		CountParameters());
446	return NULL;
447}
448
449
450bool
451BParameterWeb::IsFixedSize() const
452{
453	return false;
454}
455
456
457type_code
458BParameterWeb::TypeCode() const
459{
460	return B_MEDIA_PARAMETER_WEB_TYPE;
461}
462
463
464ssize_t
465BParameterWeb::FlattenedSize() const
466{
467	CALLED();
468
469/*
470	//--------BEGIN-CORE-BPARAMETERWEB-STRUCT-----------
471	?? 0x01030506: 4 bytes
472	??: 4 bytes (is always 1)
473	Group Count: 4 bytes
474	Node (as media_node): 0x18 bytes (decimal 24 bytes)
475		//for each Group BEGIN
476		Flattened Group Size: 4 bytes
477		Flattened Group: 'Flattened Group Size' bytes
478		//for each Group END
479		//for each Group BEGIN
480		??: 4 bytes (never get written to (holds uninitialized value))
481		//for each Group END
482	//---------END-CORE-BPARAMETERWEB-STRUCT--------------
483*/
484	//36 guaranteed bytes, variable after that.
485	ssize_t size = sizeof(int32) + 2 * sizeof(int32) + sizeof(media_node);
486
487	for (int32 i = fGroups->CountItems(); i-- > 0;) {
488		BParameterGroup* group
489			= static_cast<BParameterGroup*>(fGroups->ItemAt(i));
490		if (group != NULL) {
491			size += 4 + group->FlattenedSize();
492				// 4 bytes for the flattened size
493		}
494	}
495
496	return size;
497}
498
499
500status_t
501BParameterWeb::Flatten(void* buffer, ssize_t size) const
502{
503	CALLED();
504
505	if (buffer == NULL)
506		return B_NO_INIT;
507
508	ssize_t actualSize = BParameterWeb::FlattenedSize();
509	if (size < actualSize)
510		return B_NO_MEMORY;
511
512	void* bufferStart = buffer;
513
514	write_to_buffer<int32>(&buffer, kParameterWebMagic);
515	write_to_buffer<int32>(&buffer, kCurrentParameterWebVersion);
516
517	// flatten all groups into this buffer
518
519	int32 count = fGroups->CountItems();
520	write_to_buffer<int32>(&buffer, count);
521
522	write_to_buffer<media_node>(&buffer, fNode);
523
524	for (int32 i = 0; i < count; i++) {
525		BParameterGroup* group
526			= static_cast<BParameterGroup*>(fGroups->ItemAt(i));
527		if (group == NULL) {
528			ERROR("BParameterWeb::Flatten(): group is NULL\n");
529			continue;
530		}
531
532		ssize_t groupSize = group->FlattenedSize();
533		if (groupSize > size_left(size, bufferStart, buffer)) {
534			ERROR("BParameterWeb::Flatten(): buffer too small\n");
535			return B_BAD_VALUE;
536		}
537
538		write_to_buffer<ssize_t>(&buffer, groupSize);
539
540		// write the flattened sub group
541		status_t status = group->Flatten(buffer, groupSize);
542		if (status < B_OK)
543			return status;
544
545		skip_in_buffer(&buffer, groupSize);
546	}
547
548	return B_OK;
549}
550
551
552bool
553BParameterWeb::AllowsTypeCode(type_code code) const
554{
555	return code == TypeCode();
556}
557
558
559status_t
560BParameterWeb::Unflatten(type_code code, const void* buffer, ssize_t size)
561{
562	CALLED();
563
564	if (!AllowsTypeCode(code)) {
565		ERROR("BParameterWeb::Unflatten(): wrong type code\n");
566		return B_BAD_TYPE;
567	}
568
569	if (buffer == NULL) {
570		ERROR("BParameterWeb::Unflatten(): NULL buffer pointer\n");
571		return B_NO_INIT;
572	}
573
574	// if the buffer is smaller than the size needed to read the
575	// signature field, the mystery field, the group count, and the Node, then there is a problem
576	if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(int32)
577			+ sizeof(ssize_t) + sizeof(media_node))) {
578		ERROR("BParameterWeb::Unflatten(): size to small\n");
579		return B_ERROR;
580	}
581
582	const void* bufferStart = buffer;
583
584	uint32 magic = read_from_buffer<uint32>(&buffer);
585	bool isSwapped = false;
586
587	if (magic == B_SWAP_INT32(kParameterWebMagic)) {
588		isSwapped = true;
589		magic = B_SWAP_INT32(magic);
590	}
591	if (magic != kParameterWebMagic)
592		return B_BAD_DATA;
593
594	// Note, it's not completely sure that this field is the version
595	// information - but it doesn't seem to have another purpose
596	int32 version = read_from_buffer_swap32<int32>(&buffer, isSwapped);
597	if (version != kCurrentParameterWebVersion) {
598		ERROR("BParameterWeb::Unflatten(): wrong version %" B_PRId32 " (%"
599			B_PRIx32 ")?!\n", version, version);
600		return B_ERROR;
601	}
602
603	for (int32 i = 0; i < fGroups->CountItems(); i++) {
604		delete static_cast<BParameterGroup*>(fGroups->ItemAt(i));
605	}
606	fGroups->MakeEmpty();
607
608	int32 count = read_from_buffer_swap32<int32>(&buffer, isSwapped);
609
610	fNode = read_from_buffer<media_node>(&buffer);
611	if (isSwapped)
612		swap_data(B_INT32_TYPE, &fNode, sizeof(media_node), B_SWAP_ALWAYS);
613
614	for (int32 i = 0; i < count; i++) {
615		ssize_t groupSize
616			= read_from_buffer_swap32<ssize_t>(&buffer, isSwapped);
617		if (groupSize > size_left(size, bufferStart, buffer)) {
618			ERROR("BParameterWeb::Unflatten(): buffer too small\n");
619			return B_BAD_DATA;
620		}
621
622		BParameterGroup* group = new BParameterGroup(this, "unnamed");
623		status_t status = group->Unflatten(group->TypeCode(), buffer,
624			groupSize);
625		if (status < B_OK) {
626			ERROR("BParameterWeb::Unflatten(): unflatten group failed\n");
627			delete group;
628			return status;
629		}
630
631		skip_in_buffer(&buffer, groupSize);
632
633		fGroups->AddItem(group);
634	}
635
636	// fix all references (ParameterAt() style)
637
638	BList groups(*fGroups);
639
640	for (int32 i = 0; i < groups.CountItems(); i++) {
641		BParameterGroup* group
642			= static_cast<BParameterGroup*>(groups.ItemAt(i));
643
644		for (int32 index = group->CountParameters(); index-- > 0;) {
645			BParameter* parameter
646				= static_cast<BParameter*>(group->ParameterAt(index));
647
648			parameter->FixRefs(*fOldRefs, *fNewRefs);
649		}
650
651		if (group->fGroups != NULL)
652			groups.AddList(group->fGroups);
653	}
654
655	fOldRefs->MakeEmpty();
656	fNewRefs->MakeEmpty();
657
658	return B_OK;
659}
660
661
662void
663BParameterWeb::AddRefFix(void* oldItem, void* newItem)
664{
665	fOldRefs->AddItem(oldItem);
666	fNewRefs->AddItem(newItem);
667}
668
669
670//	#pragma mark - BParameterGroup
671
672
673BParameterGroup::BParameterGroup(BParameterWeb* web, const char* name)
674	:
675	fWeb(web),
676	fFlags(0)
677{
678	CALLED();
679	TRACE("BParameterGroup: web = %p, name = \"%s\"\n", web, name);
680
681	fName = strndup(name, 255);
682
683	fControls = new BList();
684	fGroups = new BList();
685}
686
687
688BParameterGroup::~BParameterGroup()
689{
690	CALLED();
691
692	for (int i = fControls->CountItems(); i-- > 0;) {
693		delete static_cast<BParameter*>(fControls->ItemAt(i));
694	}
695	delete fControls;
696
697	for (int i = fGroups->CountItems(); i-- > 0;) {
698		delete static_cast<BParameterGroup*>(fGroups->ItemAt(i));
699	}
700	delete fGroups;
701
702	free(fName);
703}
704
705
706BParameterWeb*
707BParameterGroup::Web() const
708{
709	return fWeb;
710}
711
712
713const char*
714BParameterGroup::Name() const
715{
716	return fName;
717}
718
719
720void
721BParameterGroup::SetFlags(uint32 flags)
722{
723	fFlags = flags;
724}
725
726
727uint32
728BParameterGroup::Flags() const
729{
730	return fFlags;
731}
732
733
734BNullParameter*
735BParameterGroup::MakeNullParameter(int32 id, media_type mediaType,
736	const char* name, const char* kind)
737{
738	CALLED();
739
740	BNullParameter* parameter = new(std::nothrow) BNullParameter(id, mediaType,
741		fWeb, name, kind);
742	if (parameter == NULL)
743		return NULL;
744
745	parameter->fGroup = this;
746	fControls->AddItem(parameter);
747
748	return parameter;
749}
750
751
752BContinuousParameter*
753BParameterGroup::MakeContinuousParameter(int32 id, media_type mediaType,
754	const char* name, const char* kind, const char* unit,
755	float minimum, float maximum, float stepping)
756{
757	CALLED();
758
759	BContinuousParameter* parameter
760		= new(std::nothrow) BContinuousParameter(id, mediaType, fWeb, name,
761			kind, unit, minimum, maximum, stepping);
762	if (parameter == NULL)
763		return NULL;
764
765	parameter->fGroup = this;
766	fControls->AddItem(parameter);
767
768	return parameter;
769}
770
771
772BDiscreteParameter*
773BParameterGroup::MakeDiscreteParameter(int32 id, media_type mediaType,
774	const char* name, const char* kind)
775{
776	CALLED();
777
778	BDiscreteParameter* parameter = new(std::nothrow) BDiscreteParameter(id,
779		mediaType, fWeb, name, kind);
780	if (parameter == NULL)
781		return NULL;
782
783	parameter->fGroup = this;
784	fControls->AddItem(parameter);
785
786	return parameter;
787}
788
789
790BTextParameter*
791BParameterGroup::MakeTextParameter(int32 id, media_type mediaType,
792	const char* name, const char* kind, size_t maxBytes)
793{
794	CALLED();
795
796	BTextParameter* parameter = new(std::nothrow) BTextParameter(id, mediaType,
797		fWeb, name, kind, maxBytes);
798	if (parameter == NULL)
799		return NULL;
800
801	parameter->fGroup = this;
802	fControls->AddItem(parameter);
803
804	return parameter;
805}
806
807
808BParameterGroup*
809BParameterGroup::MakeGroup(const char* name)
810{
811	CALLED();
812
813	BParameterGroup* group = new(std::nothrow) BParameterGroup(fWeb, name);
814	if (group != NULL)
815		fGroups->AddItem(group);
816
817	return group;
818}
819
820
821int32
822BParameterGroup::CountParameters()
823{
824	return fControls->CountItems();
825}
826
827
828BParameter*
829BParameterGroup::ParameterAt(int32 index)
830{
831	return static_cast<BParameter*>(fControls->ItemAt(index));
832}
833
834
835int32
836BParameterGroup::CountGroups()
837{
838	return fGroups->CountItems();
839}
840
841
842BParameterGroup*
843BParameterGroup::GroupAt(int32 index)
844{
845	return static_cast<BParameterGroup*>(fGroups->ItemAt(index));
846}
847
848
849bool
850BParameterGroup::IsFixedSize() const
851{
852	return false;
853}
854
855
856type_code
857BParameterGroup::TypeCode() const
858{
859	return B_MEDIA_PARAMETER_GROUP_TYPE;
860}
861
862
863ssize_t
864BParameterGroup::FlattenedSize() const
865{
866	CALLED();
867
868	/*
869		//--------BEGIN-CORE-BPARAMETERGROUP-STRUCT-----------
870		?? (0x03040507 OR 0x03040509 depending if the flags field is included or not???): 4 bytes
871		(possible) Flags: 4 bytes
872		Name String Length: 1 byte (??)
873			Name String: 'Name String Length' bytes
874		Param Count: 4 bytes
875			//for each Param BEGIN
876			Pointer: 4 bytes
877			Parameter Type: 4 bytes
878			Flattened Parameter Size: 4 bytes
879			Flattened Parameter: 'Flattened Parameter Size' bytes
880			//for each Param END
881		Subgroup Count: 4 bytes
882			//for each SubGroup BEGIN
883			Pointer: 4 bytes
884			MEDIA PARAMETER GROUP TYPE('BMCG' (opposite byte order in file)): 4 bytes
885			Flattened Group Size: 4 bytes
886			Flattened Group: 'Flattened Group Size' bytes
887			//for each SubGroup END
888
889		//---------END-CORE-BPARAMETERGROUP-STRUCT--------------
890	*/
891	//13 guaranteed bytes, variable after that.
892	ssize_t size = 13;
893
894	if (fFlags != 0)
895		size += 4;
896
897	if (fName != NULL)
898		size += min_c(strlen(fName), 255);
899
900	int limit = fControls->CountItems();
901	for (int i = 0; i < limit; i++) {
902		BParameter* parameter = static_cast<BParameter*>(fControls->ItemAt(i));
903		if (parameter != NULL) {
904			// overhead for each parameter flattened
905			size += 16 + parameter->FlattenedSize();
906		}
907	}
908
909	limit = fGroups->CountItems();
910	for (int i = 0; i < limit; i++) {
911		BParameterGroup* group
912			= static_cast<BParameterGroup*>(fGroups->ItemAt(i));
913		if (group != NULL) {
914			// overhead for each group flattened
915			size += 16 + group->FlattenedSize();
916		}
917	}
918
919	return size;
920}
921
922
923status_t
924BParameterGroup::Flatten(void* buffer, ssize_t size) const
925{
926	CALLED();
927
928	if (buffer == NULL) {
929		ERROR("BParameterGroup::Flatten buffer is NULL\n");
930		return B_NO_INIT;
931	}
932
933	// NOTICE: It is important that this value is the size returned by
934	// BParameterGroup::FlattenedSize, not by a descendent's override of this method.
935	ssize_t actualSize = BParameterGroup::FlattenedSize();
936	if (size < actualSize) {
937		ERROR("BParameterGroup::Flatten size to small\n");
938		return B_NO_MEMORY;
939	}
940
941	if (fFlags != 0) {
942		write_to_buffer<int32>(&buffer, kBufferGroupMagic);
943		write_to_buffer<uint32>(&buffer, fFlags);
944	} else
945		write_to_buffer<int32>(&buffer, kBufferGroupMagicNoFlags);
946
947	write_string_to_buffer(&buffer, fName);
948
949	int32 count = fControls->CountItems();
950	write_to_buffer<int32>(&buffer, count);
951
952	for (int32 i = 0; i < count; i++) {
953		BParameter* parameter = static_cast<BParameter*>(fControls->ItemAt(i));
954		if (parameter == NULL) {
955			ERROR("BParameterGroup::Flatten(): NULL parameter\n");
956			continue;
957		}
958
959		write_to_buffer<BParameter*>(&buffer, parameter);
960		write_to_buffer<BParameter::media_parameter_type>(&buffer,
961			parameter->Type());
962
963		// flatten parameter into this buffer
964
965		ssize_t parameterSize = parameter->FlattenedSize();
966		write_to_buffer<ssize_t>(&buffer, parameterSize);
967
968		status_t status = parameter->Flatten(buffer, parameterSize);
969			// we have only that much bytes left to write in this buffer
970		if (status < B_OK)
971			return status;
972
973		skip_in_buffer(&buffer, parameterSize);
974	}
975
976	count = fGroups->CountItems();
977	write_to_buffer<int32>(&buffer, count);
978
979	for (int32 i = 0; i < count; i++) {
980		BParameterGroup* group
981			= static_cast<BParameterGroup*>(fGroups->ItemAt(i));
982		if (group == NULL) {
983			ERROR("BParameterGroup::Flatten(): NULL group\n");
984			continue;
985		}
986
987		write_to_buffer<BParameterGroup*>(&buffer, group);
988		write_to_buffer<type_code>(&buffer, group->TypeCode());
989
990		// flatten sub group into this buffer
991
992		ssize_t groupSize = group->FlattenedSize();
993		write_to_buffer<ssize_t>(&buffer, groupSize);
994
995		status_t status = group->Flatten(buffer, groupSize);
996			// we have only that much bytes left to write in this buffer
997		if (status < B_OK)
998			return status;
999
1000		skip_in_buffer(&buffer, groupSize);
1001	}
1002
1003	return B_OK;
1004}
1005
1006
1007bool
1008BParameterGroup::AllowsTypeCode(type_code code) const
1009{
1010	return code == TypeCode();
1011}
1012
1013
1014status_t
1015BParameterGroup::Unflatten(type_code code, const void* buffer, ssize_t size)
1016{
1017	CALLED();
1018
1019	if (!AllowsTypeCode(code)) {
1020		ERROR("BParameterGroup::Unflatten() wrong type code\n");
1021		return B_BAD_TYPE;
1022	}
1023
1024	if (buffer == NULL) {
1025		ERROR("BParameterGroup::Unflatten() buffer is NULL\n");
1026		return B_NO_INIT;
1027	}
1028
1029	// if the buffer is smaller than the size needed to read the
1030	// signature field, then there is a problem
1031	if (size < static_cast<ssize_t>(sizeof(int32))) {
1032		ERROR("BParameterGroup::Unflatten() size to small\n");
1033		return B_ERROR;
1034	}
1035
1036	const void* bufferStart = buffer;
1037		// used to compute the rest length of the buffer when needed
1038
1039	uint32 magic = read_from_buffer<uint32>(&buffer);
1040	bool isSwapped = false;
1041
1042	if (magic == B_SWAP_INT32(kBufferGroupMagic)
1043		|| magic == B_SWAP_INT32(kBufferGroupMagicNoFlags)) {
1044		isSwapped = true;
1045		magic = B_SWAP_INT32(magic);
1046	}
1047
1048	if (magic == kBufferGroupMagic)
1049		fFlags = read_from_buffer_swap32<int32>(&buffer, isSwapped);
1050	else if (magic == kBufferGroupMagicNoFlags)
1051		fFlags = 0;
1052	else
1053		return B_BAD_TYPE;
1054
1055	if (read_string_from_buffer(&buffer, &fName,
1056			size - (ssize_t)((uint8*)buffer - (uint8*)bufferStart)) < B_OK)
1057		return B_BAD_VALUE;
1058
1059	// Clear all existing parameters/subgroups
1060	for (int32 i = 0; i < fControls->CountItems(); i++) {
1061		delete static_cast<BParameter*>(fControls->ItemAt(i));
1062	}
1063	fControls->MakeEmpty();
1064
1065	for (int32 i = 0; i < fGroups->CountItems(); i++) {
1066		delete static_cast<BParameterGroup*>(fGroups->ItemAt(i));
1067	}
1068	fGroups->MakeEmpty();
1069
1070	// unflatten parameter list
1071
1072	int32 count = read_from_buffer_swap32<int32>(&buffer, isSwapped);
1073	if (count < 0 || count * kAdditionalParameterSize
1074			> size_left(size, bufferStart, buffer))
1075		return B_BAD_VALUE;
1076
1077	for (int32 i = 0; i < count; i++) {
1078		// make sure we can read as many bytes
1079		if (size_left(size, bufferStart, buffer) < 12)
1080			return B_BAD_VALUE;
1081
1082		BParameter* oldPointer = read_pointer_from_buffer_swap<BParameter*>(
1083			&buffer, isSwapped);
1084		BParameter::media_parameter_type mediaType
1085			= read_from_buffer_swap32<BParameter::media_parameter_type>(&buffer,
1086				isSwapped);
1087
1088		ssize_t parameterSize = read_from_buffer_swap32<ssize_t>(&buffer,
1089			isSwapped);
1090		if (parameterSize > size_left(size, bufferStart, buffer))
1091			return B_BAD_VALUE;
1092
1093		BParameter* parameter = MakeControl(mediaType);
1094		if (parameter == NULL) {
1095			ERROR("BParameterGroup::Unflatten(): MakeControl() failed\n");
1096			return B_ERROR;
1097		}
1098
1099		status_t status = parameter->Unflatten(parameter->TypeCode(), buffer,
1100			parameterSize);
1101		if (status < B_OK) {
1102			ERROR("BParameterGroup::Unflatten(): parameter->Unflatten() failed\n");
1103			delete parameter;
1104			return status;
1105		}
1106
1107		skip_in_buffer(&buffer, parameterSize);
1108
1109		// add the item to the list
1110		parameter->fGroup = this;
1111		parameter->fWeb = fWeb;
1112		fControls->AddItem(parameter);
1113
1114		// add it's old pointer value to the RefFix list kept by the owner web
1115		if (fWeb != NULL)
1116			fWeb->AddRefFix(oldPointer, parameter);
1117	}
1118
1119	// unflatten sub groups
1120
1121	count = read_from_buffer_swap32<int32>(&buffer, isSwapped);
1122	if (count < 0 || count * kAdditionalParameterGroupSize
1123			> size_left(size, bufferStart, buffer))
1124		return B_BAD_VALUE;
1125
1126	for (int32 i = 0; i < count; i++) {
1127		// make sure we can read as many bytes
1128		if (size_left(size, bufferStart, buffer) < 12)
1129			return B_BAD_VALUE;
1130
1131		BParameterGroup* oldPointer = read_pointer_from_buffer_swap<
1132			BParameterGroup*>(&buffer, isSwapped);
1133		type_code type = read_from_buffer_swap32<type_code>(&buffer, isSwapped);
1134
1135		ssize_t groupSize
1136			= read_from_buffer_swap32<ssize_t>(&buffer, isSwapped);
1137		if (groupSize > size_left(size, bufferStart, buffer))
1138			return B_BAD_VALUE;
1139
1140		BParameterGroup* group = new BParameterGroup(fWeb, "sub-unnamed");
1141		if (group == NULL) {
1142			ERROR("BParameterGroup::Unflatten(): MakeGroup() failed\n");
1143			return B_ERROR;
1144		}
1145
1146		status_t status = group->Unflatten(type, buffer, groupSize);
1147		if (status != B_OK) {
1148			ERROR("BParameterGroup::Unflatten(): group->Unflatten() failed\n");
1149			delete group;
1150			return status;
1151		}
1152
1153		skip_in_buffer(&buffer, groupSize);
1154
1155		fGroups->AddItem(group);
1156
1157		// add it's old pointer value to the RefFix list kept by the owner web
1158		if (fWeb != NULL)
1159			fWeb->AddRefFix(oldPointer, group);
1160	}
1161
1162	return B_OK;
1163}
1164
1165
1166/*!	Creates an uninitialized parameter of the specified type.
1167	Unlike the BParameterGroup::MakeXXXParameter() type of methods, this
1168	method does not add the parameter to this group automatically.
1169*/
1170BParameter*
1171BParameterGroup::MakeControl(int32 type)
1172{
1173	CALLED();
1174
1175	switch (type) {
1176		case BParameter::B_NULL_PARAMETER:
1177			return new BNullParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL, NULL);
1178
1179		case BParameter::B_DISCRETE_PARAMETER:
1180			return new BDiscreteParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL,
1181				NULL);
1182
1183		case BParameter::B_CONTINUOUS_PARAMETER:
1184			return new BContinuousParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL,
1185				NULL, NULL, 0, 0, 0);
1186
1187		case BParameter::B_TEXT_PARAMETER:
1188			return new BTextParameter(-1, B_MEDIA_NO_TYPE, NULL, NULL, NULL, 0);
1189
1190		default:
1191			ERROR("BParameterGroup::MakeControl unknown type %" B_PRId32 "\n",
1192				type);
1193			return NULL;
1194	}
1195}
1196
1197
1198//	#pragma mark - BParameter
1199
1200
1201BParameter::media_parameter_type
1202BParameter::Type() const
1203{
1204	return fType;
1205}
1206
1207
1208BParameterWeb*
1209BParameter::Web() const
1210{
1211	return fWeb;
1212}
1213
1214
1215BParameterGroup*
1216BParameter::Group() const
1217{
1218	return fGroup;
1219}
1220
1221
1222const char*
1223BParameter::Name() const
1224{
1225	return fName;
1226}
1227
1228
1229const char*
1230BParameter::Kind() const
1231{
1232	return fKind;
1233}
1234
1235
1236const char*
1237BParameter::Unit() const
1238{
1239	return fUnit;
1240}
1241
1242
1243int32
1244BParameter::ID() const
1245{
1246	return fID;
1247}
1248
1249
1250void
1251BParameter::SetFlags(uint32 flags)
1252{
1253	fFlags = flags;
1254}
1255
1256
1257uint32
1258BParameter::Flags() const
1259{
1260	return fFlags;
1261}
1262
1263
1264status_t
1265BParameter::GetValue(void* buffer, size_t* _size, bigtime_t* _when)
1266{
1267	CALLED();
1268
1269	if (buffer == NULL || _size == NULL)
1270		return B_BAD_VALUE;
1271
1272	size_t size = *_size;
1273	if (size <= 0)
1274		return B_NO_MEMORY;
1275
1276	if (fWeb == NULL) {
1277		ERROR("BParameter::GetValue: no parent BParameterWeb\n");
1278		return B_NO_INIT;
1279	}
1280
1281	media_node node = fWeb->Node();
1282	if (IS_INVALID_NODE(node)) {
1283		ERROR("BParameter::GetValue: the parent BParameterWeb is not assigned to a BMediaNode\n");
1284		return B_NO_INIT;
1285	}
1286
1287	controllable_get_parameter_data_request request;
1288	controllable_get_parameter_data_reply reply;
1289
1290	area_id area;
1291	void* data;
1292	if (size > MAX_PARAMETER_DATA) {
1293		// create an area if large data needs to be transfered
1294		area = create_area("get parameter data", &data, B_ANY_ADDRESS,
1295			ROUND_UP_TO_PAGE(size), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
1296		if (area < B_OK) {
1297			ERROR("BParameter::GetValue can't create area of %ld bytes\n",
1298				size);
1299			return B_NO_MEMORY;
1300		}
1301	} else {
1302		area = -1;
1303		data = reply.raw_data;
1304	}
1305
1306	request.parameter_id = fID;
1307	request.request_size = size;
1308	request.area = area;
1309
1310	status_t status = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_DATA,
1311		&request, sizeof(request), &reply, sizeof(reply));
1312	if (status == B_OK) {
1313		// we don't want to copy more than the buffer provides
1314		if (reply.size < size)
1315			size = reply.size;
1316
1317		memcpy(buffer, data, size);
1318
1319		// store reported values
1320
1321		*_size = reply.size;
1322		if (_when != NULL)
1323			*_when = reply.last_change;
1324	} else {
1325		ERROR("BParameter::GetValue parameter '%s' querying node %d, "
1326			"port %d failed: %s\n",  fName, (int)node.node, (int)node.port,
1327			strerror(status));
1328	}
1329
1330	if (area >= B_OK)
1331		delete_area(area);
1332
1333	return status;
1334}
1335
1336
1337status_t
1338BParameter::SetValue(const void* buffer, size_t size, bigtime_t when)
1339{
1340	CALLED();
1341
1342	if (buffer == 0)
1343		return B_BAD_VALUE;
1344	if (size <= 0)
1345		return B_NO_MEMORY;
1346
1347	if (fWeb == 0) {
1348		ERROR("BParameter::SetValue: no parent BParameterWeb\n");
1349		return B_NO_INIT;
1350	}
1351
1352	media_node node = fWeb->Node();
1353	if (IS_INVALID_NODE(node)) {
1354		ERROR("BParameter::SetValue: the parent BParameterWeb is not assigned "
1355			"to a BMediaNode\n");
1356		return B_NO_INIT;
1357	}
1358
1359	controllable_set_parameter_data_request request;
1360	controllable_set_parameter_data_reply reply;
1361	area_id area;
1362	void* data;
1363
1364	if (size > MAX_PARAMETER_DATA) {
1365		// create an area if large data needs to be transfered
1366		area = create_area("set parameter data", &data, B_ANY_ADDRESS,
1367			ROUND_UP_TO_PAGE(size), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
1368		if (area < B_OK) {
1369			ERROR("BParameter::SetValue can't create area of %ld bytes\n", size);
1370			return B_NO_MEMORY;
1371		}
1372	} else {
1373		area = -1;
1374		data = request.raw_data;
1375	}
1376
1377	memcpy(data, buffer, size);
1378	request.parameter_id = fID;
1379	request.when = when;
1380	request.area = area;
1381	request.size = size;
1382
1383	status_t status = QueryPort(node.port, CONTROLLABLE_SET_PARAMETER_DATA,
1384		&request, sizeof(request), &reply, sizeof(reply));
1385	if (status != B_OK) {
1386		ERROR("BParameter::SetValue querying node failed: %s\n",
1387			strerror(status));
1388	}
1389
1390	if (area != -1)
1391		delete_area(area);
1392
1393	return status;
1394}
1395
1396
1397int32
1398BParameter::CountChannels()
1399{
1400	return fChannels;
1401}
1402
1403
1404void
1405BParameter::SetChannelCount(int32 count)
1406{
1407	fChannels = count;
1408}
1409
1410
1411media_type
1412BParameter::MediaType()
1413{
1414	return fMediaType;
1415}
1416
1417
1418void
1419BParameter::SetMediaType(media_type type)
1420{
1421	fMediaType = type;
1422}
1423
1424
1425int32
1426BParameter::CountInputs()
1427{
1428	return fInputs->CountItems();
1429}
1430
1431
1432BParameter*
1433BParameter::InputAt(int32 index)
1434{
1435	return static_cast<BParameter*>(fInputs->ItemAt(index));
1436}
1437
1438
1439void
1440BParameter::AddInput(BParameter* input)
1441{
1442	CALLED();
1443
1444	// BeBook has this method returning a status value,
1445	// but it should be updated
1446	if (input == NULL)
1447		return;
1448
1449	if (fInputs->HasItem(input)) {
1450		// if already in input list, don't duplicate.
1451		return;
1452	}
1453
1454	fInputs->AddItem(input);
1455	input->AddOutput(this);
1456}
1457
1458
1459int32
1460BParameter::CountOutputs()
1461{
1462	return fOutputs->CountItems();
1463}
1464
1465
1466BParameter*
1467BParameter::OutputAt(int32 index)
1468{
1469	return static_cast<BParameter*>(fOutputs->ItemAt(index));
1470}
1471
1472
1473void
1474BParameter::AddOutput(BParameter* output)
1475{
1476	CALLED();
1477
1478	// BeBook has this method returning a status value,
1479	// but it should be updated
1480	if (output == NULL)
1481		return;
1482
1483	if (fOutputs->HasItem(output)) {
1484		// if already in output list, don't duplicate.
1485		return;
1486	}
1487
1488	fOutputs->AddItem(output);
1489	output->AddInput(this);
1490}
1491
1492
1493bool
1494BParameter::IsFixedSize() const
1495{
1496	return false;
1497}
1498
1499
1500type_code
1501BParameter::TypeCode() const
1502{
1503	return B_MEDIA_PARAMETER_TYPE;
1504}
1505
1506
1507ssize_t
1508BParameter::FlattenedSize() const
1509{
1510	CALLED();
1511	/*
1512		?? (0x02040607): 4 bytes
1513		BParameter Struct Size (in bytes): 4 bytes
1514		ID: 4 bytes
1515		Name String Length: 1 byte (??)
1516			Name String: 'Name String Length' bytes
1517		Kind String Length: 1 byte (??)
1518			Kind String: 'Kind String Length' bytes
1519		Unit String Length: 1 byte (??)
1520			Unit String: 'Unit String Length' bytes
1521		Inputs Count: 4 bytes
1522			Inputs (pointers): ('Inputs Count')*4 bytes
1523		Outputs Count: 4 bytes
1524			Outputs (pointers): ('Outputs Count')*4 bytes
1525		Media Type: 4 bytes
1526		ChannelCount: 4 bytes
1527		Flags: 4 bytes
1528	*/
1529	//35 bytes are guaranteed, after that, add the variable length parts.
1530	ssize_t size = 35;
1531
1532	if (fName != NULL)
1533		size += strlen(fName);
1534	if (fKind != NULL)
1535		size += strlen(fKind);
1536	if (fUnit != NULL)
1537		size += strlen(fUnit);
1538
1539	size += fInputs->CountItems() * sizeof(BParameter*);
1540	size += fOutputs->CountItems() * sizeof(BParameter*);
1541
1542	return size;
1543}
1544
1545
1546status_t
1547BParameter::Flatten(void* buffer, ssize_t size) const
1548{
1549	CALLED();
1550
1551	if (buffer == NULL) {
1552		ERROR("BParameter::Flatten buffer is NULL\n");
1553		return B_NO_INIT;
1554	}
1555
1556	// NOTICE: It is important that this value is the size returned by
1557	// BParameter::FlattenedSize(), not by a descendent's override of this method.
1558	ssize_t actualSize = BParameter::FlattenedSize();
1559	if (size < actualSize) {
1560		ERROR("BParameter::Flatten(): size too small\n");
1561		return B_NO_MEMORY;
1562	}
1563
1564	write_to_buffer<uint32>(&buffer, kParameterMagic);
1565	write_to_buffer<ssize_t>(&buffer, actualSize);
1566	write_to_buffer<int32>(&buffer, fID);
1567
1568	write_string_to_buffer(&buffer, fName);
1569	write_string_to_buffer(&buffer, fKind);
1570	write_string_to_buffer(&buffer, fUnit);
1571
1572	// flatten and write the list of inputs
1573	ssize_t count = fInputs->CountItems();
1574	write_to_buffer<ssize_t>(&buffer, count);
1575
1576	if (count > 0) {
1577		memcpy(buffer, fInputs->Items(), sizeof(BParameter*) * count);
1578		skip_in_buffer(&buffer, sizeof(BParameter*) * count);
1579	}
1580
1581	// flatten and write the list of outputs
1582	count = fOutputs->CountItems();
1583	write_to_buffer<ssize_t>(&buffer, count);
1584
1585	if (count > 0) {
1586		memcpy(buffer, fOutputs->Items(), sizeof(BParameter*) * count);
1587		skip_in_buffer(&buffer, sizeof(BParameter*) * count);
1588	}
1589
1590	write_to_buffer<media_type>(&buffer, fMediaType);
1591	write_to_buffer<int32>(&buffer, fChannels);
1592	write_to_buffer<uint32>(&buffer, fFlags);
1593
1594	return B_OK;
1595}
1596
1597
1598bool
1599BParameter::AllowsTypeCode(type_code code) const
1600{
1601	return code == TypeCode();
1602}
1603
1604
1605status_t
1606BParameter::Unflatten(type_code code, const void* buffer, ssize_t size)
1607{
1608	CALLED();
1609
1610	if (!AllowsTypeCode(code)) {
1611		ERROR("BParameter::Unflatten(): wrong type code\n");
1612		return B_BAD_TYPE;
1613	}
1614
1615	if (buffer == NULL) {
1616		ERROR("BParameter::Unflatten(): buffer is NULL\n");
1617		return B_NO_INIT;
1618	}
1619
1620	// if the buffer is smaller than the size needed to read the
1621	// signature and struct size fields, then there is a problem
1622	if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(ssize_t))) {
1623		ERROR("BParameter::Unflatten() size too small\n");
1624		return B_BAD_VALUE;
1625	}
1626
1627	const void* bufferStart = buffer;
1628
1629	// check magic
1630
1631	uint32 magic = read_from_buffer<uint32>(&buffer);
1632	if (magic == B_SWAP_INT32(kParameterMagic))
1633		fSwapDetected = true;
1634	else if (magic == kParameterMagic)
1635		fSwapDetected = false;
1636	else {
1637		ERROR("BParameter::Unflatten(): bad magic\n");
1638		return B_BAD_TYPE;
1639	}
1640
1641	ssize_t parameterSize = read_from_buffer_swap32<ssize_t>(&buffer,
1642		fSwapDetected);
1643	if (parameterSize > size) {
1644		ERROR("BParameter::Unflatten(): buffer too small (%ld > %ld)\n",
1645			parameterSize, size);
1646		return B_BAD_VALUE;
1647	}
1648
1649	// if the struct doesn't meet the minimum size for
1650	// a flattened BParameter, then return an error.
1651	// MinFlattenedParamSize =
1652	// ID (4 bytes)
1653	// Name String Length (1 byte)
1654	// Kind String Length (1 byte)
1655	// Unit String Length (1 byte)
1656	// Inputs Count (4 bytes)
1657	// Outputs Count (4 bytes)
1658	// Media Type (4 bytes)
1659	// Channel Count (4 bytes)
1660	// Flags (4 bytes)
1661	// TOTAL: 27 bytes
1662	const ssize_t MinFlattenedParamSize(27);
1663	if (parameterSize < MinFlattenedParamSize) {
1664		ERROR("BParameter::Unflatten out of memory (2)\n");
1665		return B_ERROR;
1666	}
1667
1668	fID = read_from_buffer_swap32<int32>(&buffer, fSwapDetected);
1669
1670	if (read_string_from_buffer(&buffer, &fName,
1671				size_left(size, bufferStart, buffer)) < B_OK
1672		|| read_string_from_buffer(&buffer, &fKind,
1673				size_left(size, bufferStart, buffer)) < B_OK
1674		|| read_string_from_buffer(&buffer, &fUnit,
1675				size_left(size, bufferStart, buffer)) < B_OK)
1676		return B_NO_MEMORY;
1677
1678	// read the list of inputs
1679
1680	// it will directly add the pointers in the flattened message to the list;
1681	// these will be fixed to point to the real inputs/outputs later in FixRefs()
1682
1683	int32 count = read_from_buffer_swap32<int32>(&buffer, fSwapDetected);
1684
1685	fInputs->MakeEmpty();
1686	for (int32 i = 0; i < count; i++) {
1687		fInputs->AddItem(read_pointer_from_buffer_swap<BParameter * const>(
1688			&buffer, fSwapDetected));
1689	}
1690
1691	// read the list of outputs
1692
1693	count = read_from_buffer_swap32<int32>(&buffer, fSwapDetected);
1694
1695	fOutputs->MakeEmpty();
1696	for (int32 i = 0; i < count; i++) {
1697		fOutputs->AddItem(read_pointer_from_buffer_swap<BParameter * const>(
1698			&buffer, fSwapDetected));
1699	}
1700
1701	fMediaType = read_from_buffer_swap32<media_type>(&buffer, fSwapDetected);
1702	fChannels = read_from_buffer_swap32<int32>(&buffer, fSwapDetected);
1703	fFlags = read_from_buffer_swap32<uint32>(&buffer, fSwapDetected);
1704
1705	return B_OK;
1706}
1707
1708
1709BParameter::BParameter(int32 id, media_type mediaType,
1710		media_parameter_type type, BParameterWeb* web, const char* name,
1711		const char* kind, const char* unit)
1712	:
1713	fID(id),
1714	fType(type),
1715	fWeb(web),
1716	fGroup(NULL),
1717	fSwapDetected(true),
1718	fMediaType(mediaType),
1719	fChannels(1),
1720	fFlags(0)
1721{
1722	CALLED();
1723
1724	fName = strndup(name, 255);
1725	fKind = strndup(kind, 255);
1726	fUnit = strndup(unit, 255);
1727
1728	// create empty input/output lists
1729	fInputs = new BList();
1730	fOutputs = new BList();
1731}
1732
1733
1734BParameter::~BParameter()
1735{
1736	CALLED();
1737
1738	// don't worry about the fWeb/fGroup properties, you don't need
1739	// to remove yourself from a web/group since the only way in which
1740	// a parameter is destroyed is when the owner web/group destroys it
1741
1742	free(fName);
1743	free(fKind);
1744	free(fUnit);
1745
1746	delete fInputs;
1747	delete fOutputs;
1748}
1749
1750
1751/*!	Replaces references to items in the old list with the corresponding
1752	items in the updated list. The references are replaced in the input
1753	and output lists.
1754	This is called by BParameterWeb::Unflatten().
1755*/
1756void
1757BParameter::FixRefs(BList& old, BList& updated)
1758{
1759	CALLED();
1760
1761	// update inputs
1762
1763	void** items = static_cast<void**>(fInputs->Items());
1764	int32 count = fInputs->CountItems();
1765
1766	for (int32 i = 0; i < count; i++) {
1767		int32 index = old.IndexOf(items[i]);
1768		if (index >= 0)
1769			items[i] = updated.ItemAt(index);
1770		else {
1771			ERROR("BParameter::FixRefs(): No mapping found for input");
1772			items[i] = NULL;
1773		}
1774	}
1775
1776	// remove all NULL inputs (those which couldn't be mapped)
1777
1778	for (int32 i = count; i-- > 0;) {
1779		if (items[i] == NULL)
1780			fInputs->RemoveItem(i);
1781	}
1782
1783	// update outputs
1784
1785	items = static_cast<void **>(fOutputs->Items());
1786	count = fOutputs->CountItems();
1787
1788	for (int32 i = 0; i < count; i++) {
1789		int32 index = old.IndexOf(items[i]);
1790		if (index >= 0)
1791			items[i] = updated.ItemAt(index);
1792		else {
1793			ERROR("BParameter::FixRefs(): No mapping found for output");
1794			items[i] = NULL;
1795		}
1796	}
1797
1798	// remove all NULL outputs (those which couldn't be mapped)
1799
1800	for (int32 i = count; i-- > 0;) {
1801		if (items[i] == NULL)
1802			fOutputs->RemoveItem(i);
1803	}
1804}
1805
1806
1807//	#pragma mark - public BContinuousParameter
1808
1809
1810type_code
1811BContinuousParameter::ValueType()
1812{
1813	return B_FLOAT_TYPE;
1814}
1815
1816
1817float
1818BContinuousParameter::MinValue()
1819{
1820	return fMinimum;
1821}
1822
1823
1824float
1825BContinuousParameter::MaxValue()
1826{
1827	return fMaximum;
1828}
1829
1830
1831float
1832BContinuousParameter::ValueStep()
1833{
1834	return fStepping;
1835}
1836
1837
1838void
1839BContinuousParameter::SetResponse(int resp, float factor, float offset)
1840{
1841	fResponse = static_cast<response>(resp);
1842	fFactor = factor;
1843	fOffset = offset;
1844}
1845
1846
1847void
1848BContinuousParameter::GetResponse(int* _resp, float* _factor, float* _offset)
1849{
1850	if (_resp != NULL)
1851		*_resp = fResponse;
1852	if (_factor != NULL)
1853		*_factor = fFactor;
1854	if (_offset != NULL)
1855		*_offset = fOffset;
1856}
1857
1858
1859ssize_t
1860BContinuousParameter::FlattenedSize() const
1861{
1862	CALLED();
1863
1864	// only adds a fixed amount of bytes
1865	return BParameter::FlattenedSize() + kAdditionalContinuousParameterSize;
1866}
1867
1868
1869status_t
1870BContinuousParameter::Flatten(void* buffer, ssize_t size) const
1871{
1872	CALLED();
1873
1874	if (buffer == NULL) {
1875		ERROR("BContinuousParameter::Flatten(): buffer is NULL\n");
1876		return B_NO_INIT;
1877	}
1878
1879	ssize_t parameterSize = BParameter::FlattenedSize();
1880	if (size < (parameterSize + kAdditionalContinuousParameterSize)) {
1881		ERROR("BContinuousParameter::Flatten(): size to small\n");
1882		return B_NO_MEMORY;
1883	}
1884
1885	status_t status = BParameter::Flatten(buffer, size);
1886	if (status != B_OK) {
1887		ERROR("BContinuousParameter::Flatten(): BParameter::Flatten() failed\n");
1888		return status;
1889	}
1890
1891	// add our data to the general flattened BParameter
1892
1893	skip_in_buffer(&buffer, parameterSize);
1894
1895	write_to_buffer<float>(&buffer, fMinimum);
1896	write_to_buffer<float>(&buffer, fMaximum);
1897	write_to_buffer<float>(&buffer, fStepping);
1898	write_to_buffer<response>(&buffer, fResponse);
1899	write_to_buffer<float>(&buffer, fFactor);
1900	write_to_buffer<float>(&buffer, fOffset);
1901
1902	return B_OK;
1903}
1904
1905
1906status_t
1907BContinuousParameter::Unflatten(type_code code, const void* buffer,
1908	ssize_t size)
1909{
1910	CALLED();
1911
1912	// we try to check if the buffer size is long enough to hold an object
1913	// as early as possible.
1914
1915	if (!AllowsTypeCode(code)) {
1916		ERROR("BContinuousParameter::Unflatten wrong type code\n");
1917		return B_BAD_TYPE;
1918	}
1919
1920	if (buffer == NULL) {
1921		ERROR("BContinuousParameter::Unflatten buffer is NULL\n");
1922		return B_NO_INIT;
1923	}
1924
1925	// if the buffer is smaller than the size needed to read the
1926	// signature and struct size fields, then there is a problem
1927	if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(ssize_t))) {
1928		ERROR("BContinuousParameter::Unflatten size too small\n");
1929		return B_ERROR;
1930	}
1931
1932	status_t status = BParameter::Unflatten(code, buffer, size);
1933	if (status != B_OK) {
1934		ERROR("BContinuousParameter::Unflatten(): BParameter::Unflatten "
1935			"failed: %s\n", strerror(status));
1936		return status;
1937	}
1938
1939	ssize_t parameterSize = BParameter::FlattenedSize();
1940	skip_in_buffer(&buffer, parameterSize);
1941
1942	if (size < (parameterSize + kAdditionalContinuousParameterSize)) {
1943		ERROR("BContinuousParameter::Unflatten(): buffer too small\n");
1944		return B_BAD_VALUE;
1945	}
1946
1947	fMinimum = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten());
1948	fMaximum = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten());
1949	fStepping = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten());
1950	fResponse = read_from_buffer_swap32<response>(&buffer, SwapOnUnflatten());
1951	fFactor = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten());
1952	fOffset = read_from_buffer_swap32<float>(&buffer, SwapOnUnflatten());
1953
1954	return B_OK;
1955}
1956
1957
1958BContinuousParameter::BContinuousParameter(int32 id, media_type mediaType,
1959		BParameterWeb* web, const char* name, const char* kind,
1960		const char* unit, float minimum, float maximum, float stepping)
1961	: BParameter(id, mediaType, B_CONTINUOUS_PARAMETER, web, name, kind, unit),
1962	fMinimum(minimum),
1963	fMaximum(maximum),
1964	fStepping(stepping),
1965	fResponse(B_LINEAR),
1966	fFactor(1.0),
1967	fOffset(0.0)
1968{
1969	CALLED();
1970}
1971
1972
1973BContinuousParameter::~BContinuousParameter()
1974{
1975	CALLED();
1976}
1977
1978
1979//	#pragma mark - public BDiscreteParameter
1980
1981
1982type_code
1983BDiscreteParameter::ValueType()
1984{
1985	return B_INT32_TYPE;
1986}
1987
1988
1989int32
1990BDiscreteParameter::CountItems()
1991{
1992	return fValues->CountItems();
1993}
1994
1995
1996const char*
1997BDiscreteParameter::ItemNameAt(int32 index)
1998{
1999	return reinterpret_cast<const char*>(fSelections->ItemAt(index));
2000}
2001
2002
2003int32
2004BDiscreteParameter::ItemValueAt(int32 index)
2005{
2006	int32* item = static_cast<int32*>(fValues->ItemAt(index));
2007	if (item == NULL)
2008		return 0;
2009
2010	return *item;
2011}
2012
2013
2014status_t
2015BDiscreteParameter::AddItem(int32 value, const char* name)
2016{
2017	CALLED();
2018
2019	int32* valueCopy = new int32(value);
2020	char* nameCopy = strndup(name, 255);
2021	if (name != NULL && nameCopy == NULL) {
2022		delete valueCopy;
2023		return B_NO_MEMORY;
2024	}
2025
2026	if (!fValues->AddItem(valueCopy) || !fSelections->AddItem(nameCopy))
2027		return B_NO_MEMORY;
2028
2029	return B_OK;
2030}
2031
2032
2033status_t
2034BDiscreteParameter::MakeItemsFromInputs()
2035{
2036	CALLED();
2037
2038	int32 count = fInputs->CountItems();
2039	for (int32 i = 0; i < count; i++) {
2040		BParameter* parameter = static_cast<BParameter*>(fInputs->ItemAt(i));
2041		AddItem(i, parameter->Name());
2042	}
2043
2044	return B_OK;
2045}
2046
2047
2048status_t
2049BDiscreteParameter::MakeItemsFromOutputs()
2050{
2051	CALLED();
2052
2053	int32 count = fOutputs->CountItems();
2054	for (int32 i = 0; i < count; i++) {
2055		BParameter* parameter = static_cast<BParameter*>(fOutputs->ItemAt(i));
2056		AddItem(i, parameter->Name());
2057	}
2058
2059	return B_OK;
2060}
2061
2062
2063void
2064BDiscreteParameter::MakeEmpty()
2065{
2066	CALLED();
2067
2068	for (int32 i = fValues->CountItems(); i-- > 0;) {
2069		delete static_cast<int32*>(fValues->ItemAt(i));
2070	}
2071	fValues->MakeEmpty();
2072
2073	for (int32 i = fSelections->CountItems(); i-- > 0;) {
2074		free(static_cast<char*>(fSelections->ItemAt(i)));
2075	}
2076	fSelections->MakeEmpty();
2077}
2078
2079
2080ssize_t
2081BDiscreteParameter::FlattenedSize() const
2082{
2083	CALLED();
2084
2085	ssize_t size = BParameter::FlattenedSize()
2086		+ kAdditionalDiscreteParameterSize;
2087
2088	int32 count = fValues->CountItems();
2089	for (int32 i = 0; i < count; i++) {
2090		char* selection = static_cast<char*>(fSelections->ItemAt(i));
2091
2092		if (selection != NULL)
2093			size += min_c(strlen(selection), 255);
2094
2095		size += 5;
2096			// string length + value
2097	}
2098
2099	return size;
2100}
2101
2102
2103status_t
2104BDiscreteParameter::Flatten(void* buffer, ssize_t size) const
2105{
2106	CALLED();
2107
2108	if (buffer == NULL) {
2109		ERROR("BDiscreteParameter::Flatten(): buffer is NULL\n");
2110		return B_NO_INIT;
2111	}
2112
2113	ssize_t parameterSize = BParameter::FlattenedSize();
2114
2115	if (size < FlattenedSize()) {
2116		ERROR("BDiscreteParameter::Flatten(): size too small\n");
2117		return B_NO_MEMORY;
2118	}
2119
2120	status_t status = BParameter::Flatten(buffer, size);
2121	if (status != B_OK) {
2122		ERROR("BDiscreteParameter::Flatten(): BParameter::Flatten failed\n");
2123		return status;
2124	}
2125
2126	skip_in_buffer(&buffer, parameterSize);
2127
2128	int32 count = fValues->CountItems();
2129	write_to_buffer<int32>(&buffer, count);
2130
2131	// write out all value/name pairs
2132	for (int32 i = 0; i < count; i++) {
2133		const char* selection = static_cast<char*>(fSelections->ItemAt(i));
2134		const int32* value = static_cast<int32*>(fValues->ItemAt(i));
2135
2136		write_string_to_buffer(&buffer, selection);
2137		write_to_buffer<int32>(&buffer, value ? *value : 0);
2138	}
2139
2140	return B_OK;
2141}
2142
2143
2144status_t
2145BDiscreteParameter::Unflatten(type_code code, const void* buffer, ssize_t size)
2146{
2147	CALLED();
2148
2149	if (!AllowsTypeCode(code)) {
2150		ERROR("BDiscreteParameter::Unflatten(): bad type code\n");
2151		return B_BAD_TYPE;
2152	}
2153
2154	if (buffer == NULL) {
2155		ERROR("BDiscreteParameter::Unflatten(): buffer is NULL\n");
2156		return B_NO_INIT;
2157	}
2158
2159	// if the buffer is smaller than the size needed to read the
2160	// signature and struct size fields, then there is a problem
2161	if (size < static_cast<ssize_t>(sizeof(int32) + sizeof(ssize_t))) {
2162		ERROR("BDiscreteParameter::Unflatten(): size too small\n");
2163		return B_ERROR;
2164	}
2165
2166	const void* bufferStart = buffer;
2167
2168	status_t status = BParameter::Unflatten(code, buffer, size);
2169	if (status != B_OK) {
2170		ERROR("BDiscreteParameter::Unflatten(): BParameter::Unflatten failed\n");
2171		return status;
2172	}
2173
2174	ssize_t parameterSize = BParameter::FlattenedSize();
2175	skip_in_buffer(&buffer, parameterSize);
2176
2177	if (size < (parameterSize + kAdditionalDiscreteParameterSize)) {
2178		ERROR("BDiscreteParameter::Unflatten(): buffer too small\n");
2179		return B_BAD_VALUE;
2180	}
2181
2182	int32 count = read_from_buffer_swap32<int32>(&buffer, SwapOnUnflatten());
2183
2184	// clear any existing name/value pairs
2185	MakeEmpty();
2186
2187	for (int32 i = 0; i < count; i++) {
2188		char* name;
2189		if (read_string_from_buffer(&buffer, &name, size_left(size, bufferStart,
2190				buffer)) < B_OK)
2191			return B_BAD_DATA;
2192
2193		if (size_left(size, bufferStart, buffer) < (int)sizeof(int32)) {
2194			free(name);
2195			return B_BAD_DATA;
2196		}
2197
2198		int32 value = read_from_buffer_swap32<int32>(&buffer,
2199			SwapOnUnflatten());
2200
2201		AddItem(value, name);
2202		free(name);
2203	}
2204
2205	return B_OK;
2206}
2207
2208
2209BDiscreteParameter::BDiscreteParameter(int32 id, media_type mediaType,
2210	BParameterWeb* web, const char* name, const char* kind)
2211	:	BParameter(id, mediaType, B_DISCRETE_PARAMETER, web, name, kind, NULL)
2212{
2213	CALLED();
2214
2215	fSelections = new BList();
2216	fValues = new BList();
2217}
2218
2219
2220BDiscreteParameter::~BDiscreteParameter()
2221{
2222	CALLED();
2223
2224	MakeEmpty();
2225
2226	delete fSelections;
2227	delete fValues;
2228}
2229
2230
2231//	#pragma mark - public BTextParameter
2232
2233
2234size_t
2235BTextParameter::MaxBytes() const
2236{
2237	return fMaxBytes;
2238}
2239
2240
2241type_code
2242BTextParameter::ValueType()
2243{
2244	return B_FLOAT_TYPE;
2245}
2246
2247
2248ssize_t
2249BTextParameter::FlattenedSize() const
2250{
2251	return BParameter::FlattenedSize() + sizeof(fMaxBytes);
2252}
2253
2254
2255status_t
2256BTextParameter::Flatten(void* buffer, ssize_t size) const
2257{
2258	if (buffer == NULL) {
2259		ERROR("BTextParameter::Flatten(): buffer is NULL\n");
2260		return B_NO_INIT;
2261	}
2262
2263	ssize_t parameterSize = BParameter::FlattenedSize();
2264	if (size < static_cast<ssize_t>(parameterSize + sizeof(fMaxBytes))) {
2265		ERROR("BContinuousParameter::Flatten(): size to small\n");
2266		return B_NO_MEMORY;
2267	}
2268
2269	status_t status = BParameter::Flatten(buffer, size);
2270	if (status != B_OK) {
2271		ERROR("BTextParameter::Flatten(): BParameter::Flatten() failed\n");
2272		return status;
2273	}
2274
2275	// add our data to the general flattened BParameter
2276
2277	skip_in_buffer(&buffer, parameterSize);
2278
2279	write_to_buffer<uint32>(&buffer, fMaxBytes);
2280
2281	return B_OK;
2282}
2283
2284
2285status_t
2286BTextParameter::Unflatten(type_code code, const void* buffer, ssize_t size)
2287{
2288	// we try to check if the buffer size is long enough to hold an object
2289	// as early as possible.
2290
2291	if (!AllowsTypeCode(code)) {
2292		ERROR("BTextParameter::Unflatten wrong type code\n");
2293		return B_BAD_TYPE;
2294	}
2295
2296	if (buffer == NULL) {
2297		ERROR("BTextParameter::Unflatten buffer is NULL\n");
2298		return B_NO_INIT;
2299	}
2300
2301	if (size < static_cast<ssize_t>(sizeof(fMaxBytes))) {
2302		ERROR("BTextParameter::Unflatten size too small\n");
2303		return B_ERROR;
2304	}
2305
2306	status_t status = BParameter::Unflatten(code, buffer, size);
2307	if (status != B_OK) {
2308		ERROR("BTextParameter::Unflatten(): BParameter::Unflatten failed\n");
2309		return status;
2310	}
2311
2312	ssize_t parameterSize = BParameter::FlattenedSize();
2313	skip_in_buffer(&buffer, parameterSize);
2314
2315	if (size < static_cast<ssize_t>(parameterSize + sizeof(fMaxBytes))) {
2316		ERROR("BTextParameter::Unflatten(): buffer too small\n");
2317		return B_BAD_VALUE;
2318	}
2319
2320	fMaxBytes = read_from_buffer_swap32<uint32>(&buffer, SwapOnUnflatten());
2321
2322	return B_OK;
2323}
2324
2325
2326BTextParameter::BTextParameter(int32 id, media_type mediaType,
2327		BParameterWeb* web, const char* name, const char* kind,
2328		size_t maxBytes)
2329	: BParameter(id, mediaType, B_TEXT_PARAMETER, web, name, kind, NULL)
2330{
2331	fMaxBytes = maxBytes;
2332}
2333
2334
2335BTextParameter::~BTextParameter()
2336{
2337}
2338
2339
2340//	#pragma mark - public BNullParameter
2341
2342
2343type_code
2344BNullParameter::ValueType()
2345{
2346	// NULL parameters have no value type
2347	return 0;
2348}
2349
2350
2351ssize_t
2352BNullParameter::FlattenedSize() const
2353{
2354	return BParameter::FlattenedSize();
2355}
2356
2357
2358status_t
2359BNullParameter::Flatten(void* buffer, ssize_t size) const
2360{
2361	return BParameter::Flatten(buffer, size);
2362}
2363
2364
2365status_t
2366BNullParameter::Unflatten(type_code code, const void* buffer, ssize_t size)
2367{
2368	return BParameter::Unflatten(code, buffer, size);
2369}
2370
2371
2372BNullParameter::BNullParameter(int32 id, media_type mediaType,
2373		BParameterWeb* web, const char* name, const char* kind)
2374	: BParameter(id, mediaType, B_NULL_PARAMETER, web, name, kind, NULL)
2375{
2376}
2377
2378
2379BNullParameter::~BNullParameter()
2380{
2381}
2382
2383
2384//	#pragma mark - reserved functions
2385
2386
2387status_t BParameterWeb::_Reserved_ControlWeb_0(void *) { return B_ERROR; }
2388status_t BParameterWeb::_Reserved_ControlWeb_1(void *) { return B_ERROR; }
2389status_t BParameterWeb::_Reserved_ControlWeb_2(void *) { return B_ERROR; }
2390status_t BParameterWeb::_Reserved_ControlWeb_3(void *) { return B_ERROR; }
2391status_t BParameterWeb::_Reserved_ControlWeb_4(void *) { return B_ERROR; }
2392status_t BParameterWeb::_Reserved_ControlWeb_5(void *) { return B_ERROR; }
2393status_t BParameterWeb::_Reserved_ControlWeb_6(void *) { return B_ERROR; }
2394status_t BParameterWeb::_Reserved_ControlWeb_7(void *) { return B_ERROR; }
2395
2396status_t BParameterGroup::_Reserved_ControlGroup_0(void *) { return B_ERROR; }
2397status_t BParameterGroup::_Reserved_ControlGroup_1(void *) { return B_ERROR; }
2398status_t BParameterGroup::_Reserved_ControlGroup_2(void *) { return B_ERROR; }
2399status_t BParameterGroup::_Reserved_ControlGroup_3(void *) { return B_ERROR; }
2400status_t BParameterGroup::_Reserved_ControlGroup_4(void *) { return B_ERROR; }
2401status_t BParameterGroup::_Reserved_ControlGroup_5(void *) { return B_ERROR; }
2402status_t BParameterGroup::_Reserved_ControlGroup_6(void *) { return B_ERROR; }
2403status_t BParameterGroup::_Reserved_ControlGroup_7(void *) { return B_ERROR; }
2404
2405status_t BParameter::_Reserved_Control_0(void *) { return B_ERROR; }
2406status_t BParameter::_Reserved_Control_1(void *) { return B_ERROR; }
2407status_t BParameter::_Reserved_Control_2(void *) { return B_ERROR; }
2408status_t BParameter::_Reserved_Control_3(void *) { return B_ERROR; }
2409status_t BParameter::_Reserved_Control_4(void *) { return B_ERROR; }
2410status_t BParameter::_Reserved_Control_5(void *) { return B_ERROR; }
2411status_t BParameter::_Reserved_Control_6(void *) { return B_ERROR; }
2412status_t BParameter::_Reserved_Control_7(void *) { return B_ERROR; }
2413
2414status_t BContinuousParameter::_Reserved_ContinuousParameter_0(void *) { return B_ERROR; }
2415status_t BContinuousParameter::_Reserved_ContinuousParameter_1(void *) { return B_ERROR; }
2416status_t BContinuousParameter::_Reserved_ContinuousParameter_2(void *) { return B_ERROR; }
2417status_t BContinuousParameter::_Reserved_ContinuousParameter_3(void *) { return B_ERROR; }
2418status_t BContinuousParameter::_Reserved_ContinuousParameter_4(void *) { return B_ERROR; }
2419status_t BContinuousParameter::_Reserved_ContinuousParameter_5(void *) { return B_ERROR; }
2420status_t BContinuousParameter::_Reserved_ContinuousParameter_6(void *) { return B_ERROR; }
2421status_t BContinuousParameter::_Reserved_ContinuousParameter_7(void *) { return B_ERROR; }
2422
2423status_t BDiscreteParameter::_Reserved_DiscreteParameter_0(void *) { return B_ERROR; }
2424status_t BDiscreteParameter::_Reserved_DiscreteParameter_1(void *) { return B_ERROR; }
2425status_t BDiscreteParameter::_Reserved_DiscreteParameter_2(void *) { return B_ERROR; }
2426status_t BDiscreteParameter::_Reserved_DiscreteParameter_3(void *) { return B_ERROR; }
2427status_t BDiscreteParameter::_Reserved_DiscreteParameter_4(void *) { return B_ERROR; }
2428status_t BDiscreteParameter::_Reserved_DiscreteParameter_5(void *) { return B_ERROR; }
2429status_t BDiscreteParameter::_Reserved_DiscreteParameter_6(void *) { return B_ERROR; }
2430status_t BDiscreteParameter::_Reserved_DiscreteParameter_7(void *) { return B_ERROR; }
2431
2432status_t BNullParameter::_Reserved_NullParameter_0(void *) { return B_ERROR; }
2433status_t BNullParameter::_Reserved_NullParameter_1(void *) { return B_ERROR; }
2434status_t BNullParameter::_Reserved_NullParameter_2(void *) { return B_ERROR; }
2435status_t BNullParameter::_Reserved_NullParameter_3(void *) { return B_ERROR; }
2436status_t BNullParameter::_Reserved_NullParameter_4(void *) { return B_ERROR; }
2437status_t BNullParameter::_Reserved_NullParameter_5(void *) { return B_ERROR; }
2438status_t BNullParameter::_Reserved_NullParameter_6(void *) { return B_ERROR; }
2439status_t BNullParameter::_Reserved_NullParameter_7(void *) { return B_ERROR; }
2440
2441status_t BTextParameter::_Reserved_TextParameter_0(void *) { return B_ERROR; }
2442status_t BTextParameter::_Reserved_TextParameter_1(void *) { return B_ERROR; }
2443status_t BTextParameter::_Reserved_TextParameter_2(void *) { return B_ERROR; }
2444status_t BTextParameter::_Reserved_TextParameter_3(void *) { return B_ERROR; }
2445status_t BTextParameter::_Reserved_TextParameter_4(void *) { return B_ERROR; }
2446status_t BTextParameter::_Reserved_TextParameter_5(void *) { return B_ERROR; }
2447status_t BTextParameter::_Reserved_TextParameter_6(void *) { return B_ERROR; }
2448status_t BTextParameter::_Reserved_TextParameter_7(void *) { return B_ERROR; }
2449