BTranslatorRoster
is the main mechanism through which applications
interact with the Translation Kit. An application using the Translation
Kit doesn't need to worry about explicitly loading or calling add-ons;
BTranslatorRoster
transparently handles all the niggling details. The
class provides four categories of service: initialization, information,
translation, and configuration.
You can create an empty
BTranslatorRoster
(one which has no translators
loaded) by instantiating it in the usual fashion:
BTranslatorRoster *roster
= new BTranslatorRoster
;
You can then load translators to the newly-created
BTranslatorRoster
with
the AddTranslators()
method (all paths must be absolute):
roster
->AddTranslators
("/boot/home/config/add-ons/viewer/");
roster
->AddTranslators
("/system/add-ons/Translators/photos");
More commonly, you want a
BTranslatorRoster
with the default translators (those in
/boot/home/config/add-ons/Translators
,
/boot/home/config/add-ons/Datatypes
, and
/system/add-ons/Translators
).
The static member
Default()
returns just such a beast:
BTranslatorRoster *roster
= BTranslatorRoster
::Default
();
However, not al
BTranslatorRoster
s
are created equal: the object returned by
Default()
is global to the application and controlled by
BTranslatorRoster
.
As a result, you should never delete it. Additionally,
if you want to load additional translators, you're better off creating a
new instance of
BTranslatorRoster
rather than using the default one:
BTranslatorRoster *roster
= new BTranslatorRoster
;
roster
->AddTranslators
(NULL
);
roster
->AddTranslators
(...);
Applications typically ask the following questions of the Translation Kit:
Which translators are installed?
Which translations can a particular translator carry out?
Which translator is best suited for handling my conversion?
An application can determine the installed translators by calling
GetAllTranslators()
.
GetAllTranslators()
returns an array of translator_id values for the installed
translators. A translator_id is an application-wide value
assigned by
BTranslatorRoster
identifying a specific translator. The following snippet prints out the
names of the default translators:
BTranslatorRoster *roster
= BTranslatorRoster
::Default
();
int32 num_translators
, i
;
translator_id *translators;
const char *translator_name
, *translator_info
;
int32 translator_version
;
roster
->GetAllTranslators
(&translators
, &num_translators
);
for (i
=0;i
<num_translators
;i
++) {
roster
->GetTranslatorInfo
(translators
[i
], &translator_name
,
&translator_info
, &translator_version
);
printf
("%s: %s (%.2f)n", translator_name
, translator_info
,
translator_version
/100.);
}
delete [] translators
;
The translator_id is very valuable; it can be used to query
BTranslatorRoster
for specific information about a translator's
capabilities. This information comes in two nearly identical flavors:
translation_format and translator_info. They are defined in
translation/TranslationDefs.h
:
struct translation_format {
uint32 type
;
uint32 group
;
float quality
;
float capability
;
char MIME
[251];
char name
[251];
}
struct translator_info {
uint32 type
;
translator_id translator
;
uint32 group
;
float quality
;
float capability
;
char name
[251];
char MIME
[251];
}
The common fields:
Field | Description |
---|
group
| Defines the type of media the format represents, i.e. bitmap
image, sound, or video. Constants for common media types can be found
in translation/TranslatorFormats.h . |
type
| Type constant defining the specific data format. For example,
the type constant for tiff bitmaps differs from the constant for jpeg
bitmaps. |
quality
| Ability of the format to represent data of its media group.
This value ranges from a low of 0.0 (utter inability) to a high of 1.0
(encodes all relevant information). |
capability
| Ability of translator to decode the format. As with the
quality, the value ranges from 0.0 (unable to decode) to 1.0 (can
decode all variants and extensions). |
MIME
| MIME type of the format. This is a more reliable indicator of
the data format than the type field for those formats that have
standard MIME names. |
name
| Human-readable C string describing the format. May include
information about the translator as well. |
translator_info defines an additional field:
Field | Description |
---|
translator
| translator_id for the translator associated with the
structure. |
To find the media formats supported by a particular translator, call
GetInputFormats()
or
GetOutputFormats()
as appropriate. These methods
return a list of the supported input or output formats in an array of
translation_format.
Many times, however, you don't really care about individual translators;
you just want the translator best suited for handling your media stream.
In these cases, you can just call
Identify()
on the BPositionIO
.
BTranslatorRoster
will then return, in a translator_info, the translator
most suited for carrying out the translation. If you are instead
interested in finding all the translators capable of handling the data in
your stream, use
GetTranslators()
instead.
Note that some translators do not publish their input and output formats.
In these cases,
GetInputFormats()
and
GetOutputFormats()
return an empty
list of formats. The only way to tell if such a translator supports a
particular input or output format is to pass it to
Identify()
.
Although the function of
BTranslatorRoster
is to provide translation services, carrying out the translation is simple.
All it requires are the input and output
BPositionIO
streams and the type constant for the
desired output. In the simplest case, if you know the type constant you
want to convert the data into, you can let the
BTranslatorRoster
decide which translator to use:
BPositionIO *in
= ..., *out
= ...;
BTranslatorRoster *roster = BTranslatorRoster
::Default
();
uint32 desired_format_constant
= ...;
roster
->Translate
(in
, NULL
, NULL
, out
, desired_format_constant
);
Sometimes, however, you'd like the services of a specific translator. In
these cases, you can use the alternate form of
Translate()
:
BPositionIO *in
= ..., *out
= ...;
BTranslatorRoster *roster = BTranslatorRoster
::Default
();
uint32 desired_format_constant
= ...;
translator_id desired_translator_id
= ...;
roster
->Translate
(desired_translator_id
, in
, NULL
, NULL
, out
,
desired_format_constant
);
Note
The Translation Kit won't chain translators for you. If you want to
translate from
GIF
to
PNG,
you either need a translator that can convert
GIF to PNG, or you need to
perform two translations: one from GIF to an
interchange format, then another from that format to PNG.
BTranslatorRoster
provides two mechanisms for configuring the behavior of
translators: ioExtension
and
MakeConfigurationView()
.
ioExtension
is a
BMessage
that can be passed to most
BTranslatorRoster
members. It is used by the application to communicate format-specific
information to the translator. For example, it could be used to ask a
video translator to only translate the first 15 frames of the movie. The
ioExtension
field is also used by the translator to communicate
information back to the application. The translator may use it, for
example, to tell the application that it is returning a greyscale image.
A translator need not support any particular extension and there is no
way for an application to tell if a translator supports any extensions.
A set of standard ioExtension
messages can be found in
translation/TranslatorFormats.h
and are explained below:
BTranslatorRoster
contains two methods to facilitate configuration of
translators. The first method,
MakeConfigurationView()
,
instructs the translator to create a
BView
in which configuration options may be
changed. It is the responsibility of the application calling
MakeConfigurationView()
to attach the view to a
BWindow
.
The second method,
GetConfigurationMessage()
,
fills in a
BMessage
with the current
settings for a specified translator. This
BMessage
can then be passed to
Translate()
to request a translation with the settings contained within.
The task of translating data often boils down to finding the right type
constant. The following function will print the format type constants
associated with a MIME string given a
BTranslatorRoster
:
void find_constant
(BTranslatorRoster *roster
, const char *mime
)
{
translator_id *translators
;
int32 num_translators
;
roster
->GetAllTranslators
(&translators
, &num_translators
);
for (int32 i
=0;i
<num_translators
;i
++) {
const translation_format *fmts
;
int32 num_fmts
;
roster
->GetOutputFormats
(translators
[i
], &fmts
, &num_fmts
);
for (int32 j
=0;j
<num_fmts
;j
++) {
if (!strcasecmp
(fmts
[j
].MIME
, mime
))
printf
("match: %s type %8.8x (%4.4s)n",
fmts
[j
].name
, fmts
[j
].type
, &fmts
[j
].type
);
}
}
}