diff --git a/headers/os/translation/Translator.h b/headers/os/translation/Translator.h index 558bb11e3b..3b7f700f0a 100644 --- a/headers/os/translation/Translator.h +++ b/headers/os/translation/Translator.h @@ -1,127 +1,67 @@ -/*****************************************************************************/ -// File: Translator.h -// Class: BTranslator -// Reimplemented by: Michael Wilber, Translation Kit Team -// Reimplementation: 2002-06-15 -// -// Description: This file contains the BTranslator class, the base class for -// all translators that don't use the BeOS R4/R4.5 add-on method. -// -// -// Copyright (c) 2002 OpenBeOS Project -// -// Original Version: Copyright 1998, Be Incorporated, All Rights Reserved. -// Copyright 1995-1997, Jon Watte -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ #ifndef _TRANSLATOR_H #define _TRANSLATOR_H -#include + #include +#include +#include + class BTranslator : public BArchivable { -public: - BTranslator(); - // Sets refcount to 1 (the object is initially Acquired()'d once) + public: + BTranslator(); - BTranslator *Acquire(); - // return actual object and increment the refcount - - BTranslator *Release(); - // Decrements the refcount and returns pointer to the object. - // When the refcount is zero, NULL is returned and the object is - // deleted - - int32 ReferenceCount(); - // returns the refcount, THIS IS NOT THREAD SAFE, ITS ONLY FOR "FUN" + BTranslator* Acquire(); + BTranslator* Release(); - virtual const char *TranslatorName() const = 0; - // returns the short name of the translator - - virtual const char *TranslatorInfo() const = 0; - // returns a verbose name/description for the translator - - virtual int32 TranslatorVersion() const = 0; - // returns the version of the translator + int32 ReferenceCount(); + // returns the refcount, THIS IS NOT THREAD SAFE, ITS ONLY FOR "FUN" - virtual const translation_format *InputFormats(int32 *out_count) - const = 0; - // returns the input formats and the count of input formats - // that this translator supports - - virtual const translation_format *OutputFormats(int32 *out_count) - const = 0; - // returns the output formats and the count of output formats - // that this translator supports + virtual const char *TranslatorName() const = 0; + virtual const char *TranslatorInfo() const = 0; + virtual int32 TranslatorVersion() const = 0; - virtual status_t Identify(BPositionIO *inSource, - const translation_format *inFormat, BMessage *ioExtension, - translator_info *outInfo, uint32 outType) = 0; - // determines whether or not this translator can convert the - // data in inSource to the type outType + virtual const translation_format *InputFormats(int32 *out_count) + const = 0; + virtual const translation_format *OutputFormats(int32 *out_count) + const = 0; + virtual status_t Identify(BPositionIO *inSource, + const translation_format *inFormat, BMessage *ioExtension, + translator_info *outInfo, uint32 outType) = 0; + virtual status_t Translate(BPositionIO *inSource, + const translator_info *inInfo, BMessage *ioExtension, + uint32 outType, BPositionIO *outDestination) = 0; + virtual status_t MakeConfigurationView(BMessage *ioExtension, + BView **outView, BRect *outExtent); + virtual status_t GetConfigurationMessage(BMessage *ioExtension); - virtual status_t Translate(BPositionIO *inSource, - const translator_info *inInfo, BMessage *ioExtension, - uint32 outType, BPositionIO *outDestination) = 0; - // this function is the whole point of the Translation Kit, - // it translates the data in inSource to outDestination - // using the format outType + protected: + virtual ~BTranslator(); + // this is protected because the object is deleted by the + // Release() function instead of being deleted directly by + // the user - virtual status_t MakeConfigurationView(BMessage *ioExtension, - BView **outView, BRect *outExtent); - // this function creates a view that allows the user to - // configure the translator, this function is not - // required for all translators + private: + friend class BTranslatorRoster::Private; - virtual status_t GetConfigurationMessage(BMessage *ioExtension); - // puts information about the current configuration of the - // translator into ioExtension so that it can be used with - // Identify or Translate or whatever, this function is - // not required for all translators + virtual status_t _Reserved_Translator_0(int32, void *); + virtual status_t _Reserved_Translator_1(int32, void *); + virtual status_t _Reserved_Translator_2(int32, void *); + virtual status_t _Reserved_Translator_3(int32, void *); + virtual status_t _Reserved_Translator_4(int32, void *); + virtual status_t _Reserved_Translator_5(int32, void *); + virtual status_t _Reserved_Translator_6(int32, void *); + virtual status_t _Reserved_Translator_7(int32, void *); -protected: - virtual ~BTranslator(); - // this is protected because the object is deleted by the - // Release() function instead of being deleted directly by - // the user + BTranslatorRoster::Private* fOwningRoster; + translator_id fID; + int32 fRefCount; -private: - int32 fRefCount; - // number of times this object has been referenced - // by the Acquire() function - - sem_id fSem; - // used to lock object for Acquire() and Release() - - // For binary compatibility with past and future - // version of this class - uint32 fUnused[8]; - virtual status_t _Reserved_Translator_0(int32, void *); - virtual status_t _Reserved_Translator_1(int32, void *); - virtual status_t _Reserved_Translator_2(int32, void *); - virtual status_t _Reserved_Translator_3(int32, void *); - virtual status_t _Reserved_Translator_4(int32, void *); - virtual status_t _Reserved_Translator_5(int32, void *); - virtual status_t _Reserved_Translator_6(int32, void *); - virtual status_t _Reserved_Translator_7(int32, void *); + uint32 _reserved[7]; }; // The post-4.5 API suggests implementing this function in your translator @@ -132,6 +72,4 @@ private: extern "C" _EXPORT BTranslator *make_nth_translator(int32 n, image_id you, uint32 flags, ...); - - #endif /* _TRANSLATOR_H */ diff --git a/headers/os/translation/TranslatorRoster.h b/headers/os/translation/TranslatorRoster.h index 6221e9aa85..f0684ab010 100644 --- a/headers/os/translation/TranslatorRoster.h +++ b/headers/os/translation/TranslatorRoster.h @@ -1,63 +1,13 @@ -/*****************************************************************************/ -// File: TranslatorRoster.h -// Class: BTranslatorRoster -// Reimplemented by: Michael Wilber, Translation Kit Team -// Reimplementation: 2002-06-11 -// -// Description: This class is the guts of the translation kit, it makes the -// whole thing happen. It bridges the applications using this -// object with the translators that the apps need to access. -// -// -// Copyright (c) 2002 OpenBeOS Project -// -// Original Version: Copyright 1998, Be Incorporated, All Rights Reserved. -// Copyright 1995-1997, Jon Watte -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ - +/* + * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ #ifndef _TRANSLATOR_ROSTER_H #define _TRANSLATOR_ROSTER_H -#include -#include -#include -#include + #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include struct translation_format; @@ -67,174 +17,84 @@ class BPositionIO; class BQuery; class BMessage; -const char kgDefaultTranslatorPath[] = "/boot/home/config/add-ons/Translators:/boot/home/config/add-ons/Datatypes:/system/add-ons/Translators"; - -// used by BTranslatorRoster to store the list of translators -struct translator_node { - BTranslator *translator; - char *path; - image_id image; - translator_id id; - translator_node *next; -}; class BTranslatorRoster : public BArchivable { - // private, unimplemented functions - // (I'm not sure if there is a need for them anyway) - BTranslatorRoster(const BTranslatorRoster &); - BTranslatorRoster & operator=(const BTranslatorRoster &); + public: + BTranslatorRoster(); + BTranslatorRoster(BMessage* model); + virtual ~BTranslatorRoster(); -public: - BTranslatorRoster(); - // initializes the object with no translators - - BTranslatorRoster(BMessage *model); - // initializes the object and loads all translators from the - // "be:translator_path" string array in model - - ~BTranslatorRoster(); - // frees memory used by this object + static BTranslatorRoster *Default(); - virtual status_t Archive(BMessage *into, bool deep = true) const; - // store the BTranslatorRoster in into so it can later be - // used with Instantiate or the BMessage constructor - - static BArchivable *Instantiate(BMessage *from); - // creates a BTranslatorRoster object from the from archive + virtual status_t Archive(BMessage* into, bool deep = true) const; + static BArchivable* Instantiate(BMessage* from); - static const char *Version(int32 *outCurVersion, int32 *outMinVersion, - int32 inAppVersion = B_TRANSLATION_CURRENT_VERSION); - // returns the version of BTranslator roster as a string - // and through the int32 pointers; inAppVersion appears - // to be ignored + status_t AddTranslators(const char* loadPath = NULL); + status_t AddTranslator(BTranslator* translator); - static BTranslatorRoster *Default(); - // returns the "default" set of translators, they are translators - // that are loaded from the default paths - // /boot/home/config/add-ons/Translators, - // /boot/home/config/add-ons/Datatypes, - // /system/add-ons/Translators or the paths in the - // TRANSLATORS environment variable, if it exists + virtual status_t Identify(BPositionIO* source, BMessage* ioExtension, + translator_info* _info, uint32 hintType = 0, + const char* hintMIME = NULL, uint32 wantType = 0); - status_t AddTranslators(const char *load_path = NULL); - // this adds a translator, all of the translators in a folder or - // the default translators if the path is NULL + virtual status_t GetTranslators(BPositionIO* source, + BMessage* ioExtension, translator_info** _info, int32* _numInfo, + uint32 hintType = 0, const char* hintMIME = NULL, + uint32 wantType = 0); - status_t AddTranslator(BTranslator * translator); - // adds a translator that you've created yourself to the - // BTranslatorRoster; this is useful if you have translators - // that you don't want to make public or don't want loaded as - // an add-on + virtual status_t GetAllTranslators(translator_id** _list, + int32* _count); - virtual status_t Identify(BPositionIO *inSource, BMessage *ioExtension, - translator_info *outInfo, uint32 inHintType = 0, - const char *inHintMIME = NULL, uint32 inWantType = 0); - // identifies the translator that can handle the data in inSource + virtual status_t GetTranslatorInfo(translator_id translatorID, + const char** _name, const char** _info, int32* _version); - virtual status_t GetTranslators(BPositionIO *inSource, - BMessage *ioExtension, translator_info **outInfo, int32 *outNumInfo, - uint32 inHintType = 0, const char *inHintMIME = NULL, - uint32 inWantType = 0); - // finds all translators for the given type + virtual status_t GetInputFormats(translator_id translatorID, + const translation_format** _formats, int32* _numFormats); - virtual status_t GetAllTranslators(translator_id **outList, - int32 *outCount); - // returns all translators that this object contains + virtual status_t GetOutputFormats(translator_id translatorID, + const translation_format** _formats, int32* _numFormats); - virtual status_t GetTranslatorInfo(translator_id forTranslator, - const char **outName, const char **outInfo, int32 *outVersion); - // gets user visible info about a specific translator + virtual status_t Translate(BPositionIO* source, + const translator_info* info, BMessage* ioExtension, + BPositionIO* destination, uint32 wantOutType, + uint32 hintType = 0, const char* hintMIME = NULL); - virtual status_t GetInputFormats(translator_id forTranslator, - const translation_format **outFormats, int32 *outNumFormats); - // finds all input formats for a translator; - // note that translators don't always publish the formats - // that they support + virtual status_t Translate(translator_id translatorID, + BPositionIO* source, BMessage* ioExtension, + BPositionIO* destination, uint32 wantOutType); - virtual status_t GetOutputFormats(translator_id forTranslator, - const translation_format **outFormats, int32 *outNumFormats); - // finds all output formats for a translator; - // note that translators don't always publish the formats - // that they support + virtual status_t MakeConfigurationView(translator_id translatorID, + BMessage* ioExtension, BView** _view, BRect* _extent); - virtual status_t Translate(BPositionIO *inSource, - const translator_info *inInfo, BMessage *ioExtension, - BPositionIO *outDestination, uint32 inWantOutType, - uint32 inHintType = 0, const char *inHintMIME = NULL); - // the whole point of this entire kit boils down to this function; - // this translates the data in inSource into outDestination - // using the format inWantOutType + virtual status_t GetConfigurationMessage(translator_id translatorID, + BMessage* ioExtension); - virtual status_t Translate(translator_id inTranslator, - BPositionIO *inSource, BMessage *ioExtension, - BPositionIO *outDestination, uint32 inWantOutType); - // the whole point of this entire kit boils down to this function; - // this translates the data in inSource into outDestination - // using the format inWantOutType and the translator inTranslator + status_t GetRefFor(translator_id translatorID, entry_ref* ref); + bool IsTranslator(entry_ref* ref); - virtual status_t MakeConfigurationView(translator_id forTranslator, - BMessage *ioExtension, BView **outView, BRect *outExtent); - // create the view for forTranslator that allows the user - // to configure it; - // NOTE: translators are not required to support this function + status_t StartWatching(BMessenger target); + status_t StopWatching(BMessenger target); - virtual status_t GetConfigurationMessage(translator_id forTranslator, - BMessage *ioExtension); - // this is used to save the settings for a translator so that - // they can be written to disk or used in an Indentify or - // Translate call + private: + // unimplemented + BTranslatorRoster(const BTranslatorRoster& other); + BTranslatorRoster& operator=(const BTranslatorRoster& other); - status_t GetRefFor(translator_id translator, entry_ref *out_ref); - // I'm guessing that this returns the entry_ref for the - // translator add-on file for the translator_id translator + virtual void ReservedTranslatorRoster1(); + virtual void ReservedTranslatorRoster2(); + virtual void ReservedTranslatorRoster3(); + virtual void ReservedTranslatorRoster4(); + virtual void ReservedTranslatorRoster5(); + virtual void ReservedTranslatorRoster6(); -private: - void Initialize(); - // class initialization code used by all constructors - - translator_node *FindTranslatorNode(translator_id id); - // used to find the translator_node for the translator_id id - // returns NULL if the id is not valid + void _Initialize(); - status_t LoadTranslator(const char *path); - // loads the translator add-on specified by path - - void LoadDir(const char *path, int32 &loadErr, int32 &nLoaded); - // loads all of the translator add-ons from path and - // returns error status in loadErr and the number of - // translators loaded in nLoaded - - bool CheckFormats(const translation_format *inputFormats, - int32 inputFormatsCount, uint32 hintType, const char *hintMIME, - const translation_format **outFormat); - // determines how the Identify function is called + private: + class Private; - // adds the translator to the list of translators - // that this object maintains - status_t AddTranslatorToList(BTranslator *translator); - status_t AddTranslatorToList(BTranslator *translator, - const char *path, image_id image, bool acquire); + Private* fPrivate; + int32 fUnused[6]; - static BTranslatorRoster *fspDefaultTranslators; - // object that contains the default translators - - // list of translators maintained by this object - translator_node *fpTranslators; - translator_node *fpLastTranslator; - - sem_id fSem; - // semaphore used to lock this object - - // used to maintain binary combatibility with - // past and future versions of this object - int32 fUnused[4]; - virtual void ReservedTranslatorRoster1(); - virtual void ReservedTranslatorRoster2(); - virtual void ReservedTranslatorRoster3(); - virtual void ReservedTranslatorRoster4(); - virtual void ReservedTranslatorRoster5(); - virtual void ReservedTranslatorRoster6(); + static BTranslatorRoster* sDefaultRoster; }; #endif /* _TRANSLATOR_ROSTER_H */ - diff --git a/headers/private/translation/FuncTranslator.h b/headers/private/translation/FuncTranslator.h deleted file mode 100644 index a0ada3ee3b..0000000000 --- a/headers/private/translation/FuncTranslator.h +++ /dev/null @@ -1,130 +0,0 @@ -/*****************************************************************************/ -// File: FuncTranslator.h -// Class: BFuncTranslator -// Author: Michael Wilber, Translation Kit Team -// Originally Created: 2002-06-11 -// -// Description: -// This header file contains the BTranslator based object for -// function based translators, i.e. the translators which export -// each translator function individually, instead of exporting -// the make_nth_translator() function, which returns the -// translator as a class derived from BTranslator. -// -// All of the BeOS R5 translators are function based translators. -// All of the Gobe Productive translators are function based -// translators. Nearly all of the translators I've found, with -// the exception of the Haiku translators, are function based. -// -// This class is used by the OpenBeOS BTranslatorRoster -// so that function based translators, make_nth_translator() -// translators and private BTranslator objects could be -// accessed in the same way. -// -// -// Copyright (c) 2002 OpenBeOS Project -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ - -#ifndef _FUNC_TRANSLATOR_H -#define _FUNC_TRANSLATOR_H - -#include -#include -#include - -// Structure used to hold the collection of function pointers and -// public variables exported by function based translator add-ons. -struct translator_data { - const char *translatorName; - const char *translatorInfo; - int32 translatorVersion; - const translation_format *inputFormats; - const translation_format *outputFormats; - - status_t (*Identify)(BPositionIO *inSource, - const translation_format *inFormat, BMessage *ioExtension, - translator_info *outInfo, uint32 outType); - - status_t (*Translate)(BPositionIO *inSource, - const translator_info *inInfo, BMessage *ioExtension, - uint32 outType, BPositionIO *outDestination); - - status_t (*MakeConfig)(BMessage *ioExtension, - BView **outView, BRect *outExtent); - - status_t (*GetConfigMessage)(BMessage *ioExtension); -}; - -class BFuncTranslator : public BTranslator { -public: - BFuncTranslator(const translator_data *kpData); - // assigns the translator to the object - - virtual const char *TranslatorName() const; - // returns the short translator name - - virtual const char *TranslatorInfo() const; - // returns the verbose translator name/description - - virtual int32 TranslatorVersion() const; - // returns the translator's version - - virtual const translation_format *InputFormats(int32 *out_count) const; - // returns the list of supported input formats - - virtual const translation_format *OutputFormats(int32 *out_count) const; - // returns the list of supported output formats - - virtual status_t Identify(BPositionIO *inSource, - const translation_format *inFormat, BMessage *ioExtension, - translator_info *outInfo, uint32 outType); - // identifies wether or not the translator can handle - // translating the data in inSource - - virtual status_t Translate(BPositionIO *inSource, - const translator_info *inInfo, BMessage *ioExtension, uint32 outType, - BPositionIO * outDestination); - // translates the data from inSource to outDestination - // in the format outType - - virtual status_t MakeConfigurationView(BMessage *ioExtension, - BView **outView, BRect *outExtent); - // creates a view object that allows the user to change - // the translator's options - // (not required to be in all translators) - - virtual status_t GetConfigurationMessage(BMessage *ioExtension); - // returns the current settings of the translator - // (not required to be in all translators) - -protected: - virtual ~BFuncTranslator(); - // This object is deleted by calling Release(), - // it can not be deleted directly. See BTranslator in the Be Book - -private: - translator_data *fpData; - // This contains all of the member variables used by this class. - // It also contains pointers to functions that the member functions - // use to do all of the actual work for this class. -}; - -#endif // _FUNC_TRANSLATOR_H diff --git a/src/kits/translation/FuncTranslator.cpp b/src/kits/translation/FuncTranslator.cpp index 7e766ea3ad..ef5d8e5478 100644 --- a/src/kits/translation/FuncTranslator.cpp +++ b/src/kits/translation/FuncTranslator.cpp @@ -1,365 +1,133 @@ -/*****************************************************************************/ -// File: FuncTranslator.cpp -// Class: BFuncTranslator -// Author: Michael Wilber, Translation Kit Team -// Originally Created: 2002-06-11 -// -// Description: This file contains the BTranslator based object for -// function based translators, aka, the translators -// that don't use the make_nth_translator() mechanism. -// -// This class is used by the OpenBeOS BTranslatorRoster -// so that function based translators, make_nth_translator() -// translators and private BTranslator objects could be -// accessed in the same way. -// -// -// Copyright (c) 2002 OpenBeOS Project -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Wilber + * Axel Dörfler, axeld@pinc-software.de + */ -#include +/*! + This file contains the BTranslator based object for + function based translators, aka, the translators + that don't use the make_nth_translator() mechanism. -// --------------------------------------------------------------- -// Constructor -// -// Initializes class data. -// -// Preconditions: -// -// Parameters: kpData, data and function pointers that do all of -// the useful work for this class -// -// Postconditions: If kpData is freed before the BFuncTranslator, -// the BFuncTranslator will fail to work and -// could the computer to crash. kpData may point -// to a translator add-on image, this image -// should not be unloaded before the -// BFuncTranslator is freed. -// -// -// Returns: -// --------------------------------------------------------------- -BFuncTranslator::BFuncTranslator(const translator_data *kpData) : BTranslator() + This class is used by the BTranslatorRoster class + so that function based translators, make_nth_translator() + translators and private BTranslator objects could be + accessed in the same way. +*/ + + +#include "FuncTranslator.h" + + +namespace BPrivate { + +BFuncTranslator::BFuncTranslator(const translator_data& data) { - fpData = new translator_data; - if (fpData) { - fpData->translatorName = kpData->translatorName; - fpData->translatorInfo = kpData->translatorInfo; - fpData->translatorVersion = kpData->translatorVersion; - fpData->inputFormats = kpData->inputFormats; - fpData->outputFormats = kpData->outputFormats; - - fpData->Identify = kpData->Identify; - fpData->Translate = kpData->Translate; - fpData->MakeConfig = kpData->MakeConfig; - fpData->GetConfigMessage = kpData->GetConfigMessage; - } + memcpy(&fData, &data, sizeof(translator_data)); } -// --------------------------------------------------------------- -// Destructor -// -// Frees memory used by this object. Note that none of the members -// of the struct have delete used on them, this is because most -// are const pointers and the one that isn't is a regular int32. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + BFuncTranslator::~BFuncTranslator() { - delete fpData; - fpData = NULL; } -// --------------------------------------------------------------- -// TranslatorName -// -// Returns a short name for the translator that this object stores -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: NULL if fpData was not allocated successfully, -// or the short name of the translator otherwise -// --------------------------------------------------------------- -const char *BFuncTranslator::TranslatorName() const + +const char * +BFuncTranslator::TranslatorName() const { - if (fpData) - return fpData->translatorName; - else - return NULL; + return fData.name; } -// --------------------------------------------------------------- -// TranslatorInfo -// -// Returns a verbose name/description for the translator that this -// object stores -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: NULL if fpData was not allocated successfully, -// or the verbose name of the translator otherwise -// --------------------------------------------------------------- -const char *BFuncTranslator::TranslatorInfo() const + +const char * +BFuncTranslator::TranslatorInfo() const { - if (fpData) - return fpData->translatorInfo; - else - return NULL; + return fData.info; } -// --------------------------------------------------------------- -// TranslatorVersion -// -// Returns the version number for this translator -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: B_ERROR if fpData was not allocated successfully, -// or the integer representation of the translator -// version otherwise -// --------------------------------------------------------------- -int32 BFuncTranslator::TranslatorVersion() const + +int32 +BFuncTranslator::TranslatorVersion() const { - if (fpData) - return fpData->translatorVersion; - else - return B_ERROR; + return fData.version; } -// --------------------------------------------------------------- -// InputFormats -// -// Returns the list of supported input formats and the count -// of supported input formats -// -// Preconditions: -// -// Parameters: out_count, the number of input formats is stored -// here after the function completes -// -// Postconditions: -// -// Returns: NULL if out_count is NULL, -// NULL if fpData is not allocated, -// or the list of supported input formats if all is well -// --------------------------------------------------------------- -const translation_format *BFuncTranslator::InputFormats(int32 *out_count) const + +const translation_format * +BFuncTranslator::InputFormats(int32* _count) const { - if (!out_count) - return NULL; - if (fpData && fpData->inputFormats != NULL) { - int32 i; - for (i = 0; fpData->inputFormats[i].type; i++); - - *out_count = i; - return fpData->inputFormats; - } else { - *out_count = 0; + if (_count == NULL || fData.input_formats == NULL) return NULL; + + int32 count = 0; + while (fData.input_formats[count].type) { + count++; } + + *_count = count; + return fData.input_formats; } -// --------------------------------------------------------------- -// OutputFormats -// -// Returns the list of supported output formats -// -// Preconditions: -// -// Parameters: out_count, the number of output formats is stored -// here after the function completes -// -// Postconditions: -// -// Returns: NULL if out_count is NULL, -// NULL if fpData is not allocated, -// or the list of supported output formats if all is well -// --------------------------------------------------------------- -const translation_format *BFuncTranslator::OutputFormats(int32 *out_count) const + +const translation_format * +BFuncTranslator::OutputFormats(int32* _count) const { - if (!out_count) - return NULL; - if (fpData && fpData->outputFormats != NULL) { - int32 i; - for (i = 0; fpData->outputFormats[i].type; i++); - - *out_count = i; - return fpData->outputFormats; - } else { - *out_count = 0; + if (_count == NULL || fData.output_formats == NULL) return NULL; + + int32 count = 0; + while (fData.output_formats[count].type) { + count++; } + + *_count = count; + return fData.output_formats; } -// --------------------------------------------------------------- -// Identify -// -// If the translator understands how to convert the data contained -// in inSource to media type outType, it fills outInfo with -// details about the input format and return B_OK. If it doesn't -// know how to translate the data, it returns B_NO_TRANSLATOR. -// -// The actual work for this function is done by the translator -// add-on at the other end of the Identify function pointer. -// So, there's no telling the actual behavior of this function -// it depends on the translator add-on. -// -// Preconditions: -// -// Parameters: inSource, the data that wants to be converted -// inFormat, (can be null) hint about the data in -// inSource -// ioExtension, (can be null) contains additional -// information for the translator -// add-on -// outInfo, information about the capabilities -// of this translator -// outType, the output type -// -// -// Postconditions: -// -// Returns: B_OK if this translator can handle the data, -// B_ERROR, if fpData is unallocated or something else -// went wrong -// B_NO_TRANSLATOR if it can't -// --------------------------------------------------------------- -status_t BFuncTranslator::Identify(BPositionIO *inSource, - const translation_format *inFormat, BMessage *ioExtension, - translator_info *outInfo, uint32 outType) + +status_t +BFuncTranslator::Identify(BPositionIO* source, const translation_format* format, + BMessage* ioExtension, translator_info* info, uint32 type) { - if (fpData && fpData->Identify) - return fpData->Identify(inSource, inFormat, ioExtension, outInfo, - outType); - else + if (fData.identify_hook == NULL) return B_ERROR; + + return fData.identify_hook(source, format, ioExtension, info, type); } -// --------------------------------------------------------------- -// Translate -// -// The translator translates data from inSource to format outType, -// writing the output to outDestination. -// -// The actual work for this function is done by the translator -// add-on at the other end of the Translate function pointer. -// So, there's no telling the actual behavior of this function -// it depends on the translator add-on. -// -// Preconditions: -// -// Parameters: inSource, data to be translated -// inInfo, hint about the data in inSource -// ioExtension, contains configuration information -// outType, the format to translate the data to -// outDestination, where the source is translated to -// -// Postconditions: -// -// Returns: B_OK, if it converted the data -// B_NO_TRANSLATOR, if it couldn't -// B_ERROR, if fpData is unallocated or something else -// went wrong -// some other value, if it feels like it -// --------------------------------------------------------------- -status_t BFuncTranslator::Translate(BPositionIO *inSource, - const translator_info *inInfo, BMessage *ioExtension, uint32 outType, - BPositionIO *outDestination) + +status_t +BFuncTranslator::Translate(BPositionIO* source, const translator_info *info, + BMessage* ioExtension, uint32 type, BPositionIO* destination) { - if (fpData && fpData->Translate) - return fpData->Translate(inSource, inInfo, ioExtension, outType, - outDestination); - else + if (fData.translate_hook == NULL) return B_ERROR; + + return fData.translate_hook(source, info, ioExtension, type, destination); } -// --------------------------------------------------------------- -// MakeConfigurationView -// -// This creates a BView object that allows the user to configure -// the options for the translator. Not all translators support -// this feature, and for those that don't, this function -// returns B_NO_TRANSLATOR. -// -// Preconditions: -// -// Parameters: ioExtension, the settings for the translator -// outView, the view created by the translator -// outExtent, the bounds of the view -// -// Postconditions: -// -// Returns: B_ERROR, if this function is not supported -// anything else, whatever the translator feels like -// returning -// --------------------------------------------------------------- -status_t BFuncTranslator::MakeConfigurationView(BMessage *ioExtension, - BView **outView, BRect *outExtent) + +status_t +BFuncTranslator::MakeConfigurationView(BMessage* ioExtension, + BView** _view, BRect* _extent) { - if (fpData && fpData->MakeConfig) - return fpData->MakeConfig(ioExtension, outView, outExtent); - else + if (fData.make_config_hook == NULL) return B_ERROR; + + return fData.make_config_hook(ioExtension, _view, _extent); } -// --------------------------------------------------------------- -// GetConfigurationMessage -// -// This function stores the current configuration for the -// translator into ioExtension. Not all translators -// support this function. -// -// Preconditions: -// -// Parameters: ioExtension, where the configuration is stored -// -// Postconditions: -// -// Returns: B_ERROR, if function is not supported -// something else, if it is -// --------------------------------------------------------------- -status_t BFuncTranslator::GetConfigurationMessage(BMessage *ioExtension) + +status_t +BFuncTranslator::GetConfigurationMessage(BMessage* ioExtension) { - if (fpData && fpData->GetConfigMessage) - return fpData->GetConfigMessage(ioExtension); - else - return B_ERROR; + if (fData.get_config_message_hook == NULL) + return B_ERROR; + + return fData.get_config_message_hook(ioExtension); } +} // namespace BPrivate diff --git a/src/kits/translation/FuncTranslator.h b/src/kits/translation/FuncTranslator.h new file mode 100644 index 0000000000..996df98bed --- /dev/null +++ b/src/kits/translation/FuncTranslator.h @@ -0,0 +1,69 @@ +/* + * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Wilber + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef _FUNC_TRANSLATOR_H +#define _FUNC_TRANSLATOR_H + + +#include + + +// Structure used to hold the collection of function pointers and +// public variables exported by function based translator add-ons. +struct translator_data { + const char* name; + const char* info; + int32 version; + const translation_format* input_formats; + const translation_format* output_formats; + + status_t (*identify_hook)(BPositionIO* source, const translation_format* format, + BMessage* ioExtension, translator_info* outInfo, uint32 outType); + + status_t (*translate_hook)(BPositionIO* source, const translator_info* info, + BMessage* ioExtension, uint32 outType, BPositionIO* destination); + + status_t (*make_config_hook)(BMessage* ioExtension, BView** _view, BRect* _extent); + status_t (*get_config_message_hook)(BMessage* ioExtension); +}; + +namespace BPrivate { + +class BFuncTranslator : public BTranslator { + public: + BFuncTranslator(const translator_data& data); + + virtual const char *TranslatorName() const; + virtual const char *TranslatorInfo() const; + virtual int32 TranslatorVersion() const; + + virtual const translation_format *InputFormats(int32 *out_count) const; + virtual const translation_format *OutputFormats(int32 *out_count) const; + + virtual status_t Identify(BPositionIO *inSource, + const translation_format *inFormat, BMessage *ioExtension, + translator_info *outInfo, uint32 outType); + virtual status_t Translate(BPositionIO *inSource, + const translator_info *inInfo, BMessage *ioExtension, uint32 outType, + BPositionIO * outDestination); + virtual status_t MakeConfigurationView(BMessage *ioExtension, + BView **outView, BRect *outExtent); + virtual status_t GetConfigurationMessage(BMessage *ioExtension); + + protected: + virtual ~BFuncTranslator(); + // This object is deleted by calling Release(), + // it can not be deleted directly. See BTranslator in the Be Book + + private: + translator_data fData; +}; + +} // namespace BPrivate + +#endif // _FUNC_TRANSLATOR_H diff --git a/src/kits/translation/Jamfile b/src/kits/translation/Jamfile index 9e462e3a82..8ce57b5199 100644 --- a/src/kits/translation/Jamfile +++ b/src/kits/translation/Jamfile @@ -15,8 +15,8 @@ SharedLibrary libtranslation.so : TranslationUtils.cpp Translator.cpp TranslatorRoster.cpp - : - be + + : be ; Package haiku-translationkit-cvs : diff --git a/src/kits/translation/Translator.cpp b/src/kits/translation/Translator.cpp index 28dbd468f5..5699901c42 100644 --- a/src/kits/translation/Translator.cpp +++ b/src/kits/translation/Translator.cpp @@ -1,356 +1,101 @@ -/*****************************************************************************/ -// File: Translator.cpp -// Class: BTranslator -// Reimplemented by: Michael Wilber, Translation Kit Team -// Reimplementation: 2002-06-15 -// -// Description: This file contains the BTranslator class, the base class for -// all translators that don't use the BeOS R4/R4.5 add-on method. -// -// -// Copyright (c) 2002 OpenBeOS Project -// -// Original Version: Copyright 1998, Be Incorporated, All Rights Reserved. -// Copyright 1995-1997, Jon Watte -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Wilber + * Axel Dörfler, axeld@pinc-software.de + */ + + +#include "TranslatorRosterPrivate.h" #include -// Set refcount to 1 -// --------------------------------------------------------------- -// Constructor -// -// Sets refcount to 1 and creates a semaphore for locking the -// object. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + BTranslator::BTranslator() + : + fOwningRoster(NULL), + fID(0), + fRefCount(1) { - fRefCount = 1; - fSem = create_sem(1, "BTranslator Lock"); } -// --------------------------------------------------------------- -// Destructor -// -// Deletes the semaphore and resets it. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- + BTranslator::~BTranslator() { - delete_sem(fSem); - fSem = 0; + if (fOwningRoster != NULL) + fOwningRoster->TranslatorDeleted(fID); } -// --------------------------------------------------------------- -// Acquire -// -// Increments the refcount and returns a pointer to this object. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: NULL, if failed to acquire the sempaphore -// pointer to this object if successful -// --------------------------------------------------------------- + +/*! + Increments the refcount and returns a pointer to this object. +*/ BTranslator *BTranslator::Acquire() { - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - fRefCount++; - release_sem(fSem); + if (atomic_add(&fRefCount, 1) > 0) return this; - } else - return NULL; + + return NULL; } -// --------------------------------------------------------------- -// Release -// -// Decrements the refcount and returns a pointer to this object. -// When the refcount hits zero, the object is destroyed. This is -// so multiple objects can own the BTranslator and it won't get -// deleted until all of them are done with it. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: NULL, if failed to acquire the sempaphore or the -// object was just deleted -// pointer to this object if successful -// --------------------------------------------------------------- + +/*! + Decrements the refcount and returns a pointer to this object. + When the refcount hits zero, the object is destroyed. This is + so multiple objects can own the BTranslator and it won't get + deleted until all of them are done with it. + + \return NULL, if the object was just deleted +*/ BTranslator *BTranslator::Release() { - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - fRefCount--; - if (fRefCount > 0) { - release_sem(fSem); - return this; - } else { - delete this; - return NULL; - } - } else - return NULL; + int32 oldValue = atomic_add(&fRefCount, -1); + if (oldValue > 0) + return this; + + delete this; + return NULL; } -// --------------------------------------------------------------- -// ReferenceCount -// -// This function returns the current -// refcount. Notice that it is not thread safe. -// This function is only meant for fun/debugging. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: the current refcount -// --------------------------------------------------------------- -int32 BTranslator::ReferenceCount() + +int32 +BTranslator::ReferenceCount() { return fRefCount; } -// --------------------------------------------------------------- -// MakeConfigurationView -// -// This virtual function is for creating a configuration view -// for the translator so the user can change its settings. This -// base class version does nothing. Not all BTranslator derived -// object are required to support this function. -// -// Preconditions: -// -// Parameters: ioExtension, configuration data for the translator -// outView, where the created view is stored -// outText, the bounds of the view are stored here -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::MakeConfigurationView(BMessage *ioExtension, - BView **outView, BRect *outExtent) + +/*! + This virtual function is for creating a configuration view + for the translator so the user can change its settings. + This method is optional. +*/ +status_t +BTranslator::MakeConfigurationView(BMessage* ioExtension, + BView** outView, BRect* outExtent) { return B_ERROR; } -// --------------------------------------------------------------- -// GetConfigurationMessage -// -// Puts the current configuration for the translator into -// ioExtension. Not all translators are required to support -// this function -// -// Preconditions: -// -// Parameters: ioExtension, where the configuration data is stored -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::GetConfigurationMessage(BMessage *ioExtension) + +/*! + Puts the current configuration for the translator into + ioExtension. This method is optional. +*/ +status_t +BTranslator::GetConfigurationMessage(BMessage* ioExtension) { return B_ERROR; } -// --------------------------------------------------------------- -// _Reserved_Translator_0 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_0(int32 n, void *p) -{ - return B_ERROR; -} -// --------------------------------------------------------------- -// _Reserved_Translator_1 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_1(int32 n, void *p) -{ - return B_ERROR; -} - -// --------------------------------------------------------------- -// _Reserved_Translator_2 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_2(int32 n, void *p) -{ - return B_ERROR; -} - -// --------------------------------------------------------------- -// _Reserved_Translator_3 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_3(int32 n, void *p) -{ - return B_ERROR; -} - -// --------------------------------------------------------------- -// _Reserved_Translator_4 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_4(int32 n, void *p) -{ - return B_ERROR; -} - -// --------------------------------------------------------------- -// _Reserved_Translator_5 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_5(int32 n, void *p) -{ - return B_ERROR; -} - -// --------------------------------------------------------------- -// _Reserved_Translator_6 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_6(int32 n, void *p) -{ - return B_ERROR; -} - -// --------------------------------------------------------------- -// _Reserved_Translator_7 -// -// It does nothing! :) Its only here for past/future binary -// compatiblity. -// -// Preconditions: -// -// Parameters: n, not used -// p, not used -// -// Postconditions: -// -// Returns: B_ERROR -// --------------------------------------------------------------- -status_t BTranslator::_Reserved_Translator_7(int32 n, void *p) -{ - return B_ERROR; -} +status_t BTranslator::_Reserved_Translator_0(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_1(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_2(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_3(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_4(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_5(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_6(int32 n, void *p) { return B_ERROR; } +status_t BTranslator::_Reserved_Translator_7(int32 n, void *p) { return B_ERROR; } diff --git a/src/kits/translation/TranslatorRoster.cpp b/src/kits/translation/TranslatorRoster.cpp index 8d8801aa00..3074c46994 100644 --- a/src/kits/translation/TranslatorRoster.cpp +++ b/src/kits/translation/TranslatorRoster.cpp @@ -1,43 +1,36 @@ -/*****************************************************************************/ -// File: TranslatorRoster.cpp -// Class: BTranslatorRoster -// Reimplemented by: Michael Wilber, Translation Kit Team -// Reimplementation: 2002-06-11 -// -// Description: This class is the guts of the translation kit, it makes the -// whole thing happen. It bridges the applications using this -// object with the translators that the apps need to access. -// -// -// Copyright (c) 2002 OpenBeOS Project -// -// Original Version: Copyright 1998, Be Incorporated, All Rights Reserved. -// Copyright 1995-1997, Jon Watte -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Wilber + * Axel Dörfler, axeld@pinc-software.de + */ +/*! + This class is the guts of the translation kit, it makes the + whole thing happen. It bridges the applications using this + object with the translators that the apps need to access. +*/ + + +#include "FuncTranslator.h" +#include "TranslatorRosterPrivate.h" + +#include +#include +#include +#include +#include +#include +#include +#include #include -#include // for BFuncTranslator and the translator -// Initialize static member variable -BTranslatorRoster *BTranslatorRoster::fspDefaultTranslators = NULL; +#include +#include +#include + // Extensions used in the extension BMessage, defined in TranslatorFormats.h char B_TRANSLATOR_EXT_HEADER_ONLY[] = "/headerOnly"; @@ -53,274 +46,1120 @@ char B_TRANSLATOR_EXT_SOUND_MONO[] = "nois/mono"; char B_TRANSLATOR_EXT_SOUND_MARKER[] = "nois/marker"; char B_TRANSLATOR_EXT_SOUND_LOOP[] = "nois/loop"; -// --------------------------------------------------------------- -// Constructor -// -// Private, unimplimented constructor that no one should use. -// I don't think there would be much of a need for this function. -// -// Preconditions: -// -// Parameters: tr, not used -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -BTranslatorRoster::BTranslatorRoster(const BTranslatorRoster &tr) - : BArchivable() +BTranslatorRoster* BTranslatorRoster::sDefaultRoster = NULL; + + +BTranslatorRoster::Private::Private() + : BHandler("translator roster"), BLocker("translator list"), + fNextID(1) { - Initialize(); + // we're sneaking us into the BApplication + if (be_app != NULL) + be_app->AddHandler(this); } -// --------------------------------------------------------------- -// operator= -// -// Private, unimplimented function that no one should use. -// I don't know that there is a need for this function anyway. -// -// Preconditions: -// -// Parameters: tr, not used -// -// Postconditions: -// -// Returns: refernce to this object -// --------------------------------------------------------------- + +BTranslatorRoster::Private::~Private() +{ + stop_watching(this); + + if (Looper()) + Looper()->RemoveHandler(this); + + // Release all translators, so that they can delete themselves + + TranslatorMap::iterator iterator = fTranslators.begin(); + std::set images; + + while (iterator != fTranslators.end()) { + BTranslator* translator = iterator->second.translator; + + translator->fOwningRoster = NULL; + // we don't want to be notified about this anymore + + images.insert(iterator->second.image); + translator->Release(); + } + + // Unload all images + + std::set::const_iterator imageIterator = images.begin(); + + while (imageIterator != images.end()) { + unload_add_on(*imageIterator); + imageIterator++; + } +} + + +void +BTranslatorRoster::Private::MessageReceived(BMessage* message) +{ + switch (message->what) { + case B_NODE_MONITOR: + printf("translator roster node monitor: "); + message->PrintToStream(); + break; + + default: + BHandler::MessageReceived(message); + break; + } +} + + +void +BTranslatorRoster::Private::AddDefaultPaths() +{ + // add user directories first, so that they can override system translators + const directory_which paths[] = { + B_USER_ADDONS_DIRECTORY, + B_COMMON_ADDONS_DIRECTORY, + B_BEOS_ADDONS_DIRECTORY, + }; + + for (uint32 i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { + BPath path; + status_t status = find_directory(paths[i], &path, true); + if (status == B_OK && path.Append("Translators") == B_OK) + AddPath(path.Path()); + } +} + + +status_t +BTranslatorRoster::Private::AddPaths(const char* paths) +{ + if (paths == NULL) + return B_BAD_VALUE; + + status_t status = B_OK; + int32 added = 0; + + while (paths != NULL) { + const char* end = strchr(paths, ':'); + BString path; + + if (end != NULL) { + path.SetTo(paths, end - 1 - paths); + paths = end + 1; + } else { + path.SetTo(paths); + paths = NULL; + } + + // Keep the last error that occured, and return it + // but don't overwrite it, if the last path was + // added successfully. + int32 count; + status_t error = AddPath(path.String(), &count); + if (error != B_NO_ERROR) + status = error; + + added += count; + } + + if (added == 0) + return status; + + return B_OK; +} + + +status_t +BTranslatorRoster::Private::AddPath(const char* path, int32* _added) +{ + BDirectory directory(path); + status_t status = directory.InitCheck(); + if (status < B_OK) + return status; + + node_ref nodeRef; + status = directory.GetNodeRef(&nodeRef); + if (status < B_OK) + return status; + + if (Looper() != NULL) { + // watch these directories + watch_node(&nodeRef, B_WATCH_DIRECTORY, this); + } + + int32 count = 0; + int32 files = 0; + + entry_ref ref; + while (directory.GetNextRef(&ref) == B_OK) { + if (CreateTranslators(ref, count) == B_OK) + count++; + + files++; + } + + if (_added) + *_added = count; + + if (files != 0 && count == 0) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +BTranslatorRoster::Private::AddTranslator(BTranslator* translator, + image_id image = -1, const entry_ref* ref = NULL) +{ + BAutolock locker(this); + + translator_item item; + item.image = image; + if (ref != NULL) + item.ref = *ref; + + try { + fTranslators[fNextID] = item; + } catch (...) { + return B_NO_MEMORY; + } + + translator->fOwningRoster = this; + translator->fID = fNextID++; + return B_OK; +} + + +BTranslator* +BTranslatorRoster::Private::FindTranslator(translator_id id) +{ + if (!IsLocked()) { + debugger("translator must be locked!"); + return NULL; + } + + const translator_item* item = _FindTranslator(id); + if (item != NULL) + return item->translator; + + return NULL; +} + + +status_t +BTranslatorRoster::Private::GetTranslatorData(image_id image, translator_data& data) +{ + // If this is a translator add-on, it is in the C format + memset(&data, 0, sizeof(translator_data)); + + // find all the symbols + + int32* version; + if (get_image_symbol(image, "translatorName", B_SYMBOL_TYPE_DATA, (void**)&data.name) < B_OK + || get_image_symbol(image, "translatorInfo", B_SYMBOL_TYPE_DATA, (void**)&data.info) < B_OK + || get_image_symbol(image, "translatorVersion", B_SYMBOL_TYPE_DATA, (void**)&version) < B_OK || version == NULL + || get_image_symbol(image, "inputFormats", B_SYMBOL_TYPE_DATA, (void**)&data.input_formats) < B_OK + || get_image_symbol(image, "outputFormats", B_SYMBOL_TYPE_DATA, (void**)&data.output_formats) < B_OK + || get_image_symbol(image, "Identify", B_SYMBOL_TYPE_TEXT, (void**)&data.identify_hook) < B_OK + || get_image_symbol(image, "Translate", B_SYMBOL_TYPE_TEXT, (void**)&data.translate_hook) < B_OK + || get_image_symbol(image, "MakeConfig", B_SYMBOL_TYPE_TEXT, (void**)&data.make_config_hook) < B_OK + || get_image_symbol(image, "GetConfigMessage", B_SYMBOL_TYPE_TEXT, (void**)&data.get_config_message_hook) < B_OK) + return B_BAD_TYPE; + + data.version = *version; + return B_OK; +} + + +status_t +BTranslatorRoster::Private::CreateTranslators(const entry_ref& ref, int32& count) +{ + BAutolock locker(this); + + if (_FindTranslator(ref.name) != NULL) { + // keep the existing add-on + return B_OK; + } + + BPath path(&ref); + image_id image = load_add_on(path.Path()); + if (image < B_OK) + return image; + + // Function pointer used to create post R4.5 style translators + BTranslator *(*makeNthTranslator)(int32 n, image_id you, uint32 flags, ...); + + status_t status = get_image_symbol(image, "make_nth_translator", + B_SYMBOL_TYPE_TEXT, (void**)&makeNthTranslator); + if (status == B_OK) { + // If the translator add-on supports the post R4.5 + // translator creation mechanism, keep loading translators + // until MakeNthTranslator stops returning them. + BTranslator* translator = NULL; + int32 created = 0; + for (int32 n = 0; (translator = makeNthTranslator(n, image, 0)) != NULL; n++) { + if (AddTranslator(translator, image, &ref) == B_OK) { + count++; + created++; + } else { + translator->Release(); + // this will delete the translator + } + } + + if (created == 0) + unload_add_on(image); + return B_OK; + } + + // If this is a translator add-on, it is in the C format + translator_data translatorData; + status = GetTranslatorData(image, translatorData); + + // add this translator to the list + BPrivate::BFuncTranslator* translator = NULL; + if (status == B_OK) { + translator = new (std::nothrow) BPrivate::BFuncTranslator(translatorData); + if (translator == NULL) + status = B_NO_MEMORY; + } + + if (status == B_OK) + status = AddTranslator(translator, image, &ref); + + if (status == B_OK) + count++; + else + unload_add_on(image); + + return status; +} + + +status_t +BTranslatorRoster::Private::StartWatching(BMessenger target) +{ + try { + fMessengers.push_back(target); + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +status_t +BTranslatorRoster::Private::StopWatching(BMessenger target) +{ + MessengerList::iterator iterator = fMessengers.begin(); + + while (iterator != fMessengers.end()) { + if (*iterator == target) { + fMessengers.erase(iterator); + return B_OK; + } + } + + return B_BAD_VALUE; +} + + +status_t +BTranslatorRoster::Private::StoreTranslators(BMessage& archive) +{ + BAutolock locker(this); + + TranslatorMap::const_iterator iterator = fTranslators.begin(); + + while (iterator != fTranslators.end()) { + const translator_item& item = iterator->second; + BPath path(&item.ref); + if (path.InitCheck() == B_OK) + archive.AddString("be:translator_path", path.Path()); + + iterator++; + } + + return B_OK; +} + + +status_t +BTranslatorRoster::Private::Identify(BPositionIO* source, + BMessage* ioExtension, uint32 hintType, const char* hintMIME, + uint32 wantType, translator_info* _info) +{ + BAutolock locker(this); + + TranslatorMap::const_iterator iterator = fTranslators.begin(); + float bestWeight = 0.0f; + + while (iterator != fTranslators.end()) { + BTranslator& translator = *iterator->second.translator; + + status_t status = source->Seek(0, SEEK_SET); + if (status != B_OK) + return status; + + int32 formatsCount = 0; + const translation_format* formats = translator.InputFormats(&formatsCount); + const translation_format* format = _CheckHints(formats, formatsCount, hintType, + hintMIME); + + translator_info info; + if (translator.Identify(source, format, ioExtension, &info, wantType) == B_OK) { + float weight = info.quality * info.capability; + if (weight > bestWeight) { + bestWeight = weight; + + info.translator = iterator->first; + memcpy(_info, &info, sizeof(translator_info)); + } + } + } + + if (bestWeight > 0.0f) + return B_OK; + + return B_NO_TRANSLATOR; +} + + +status_t +BTranslatorRoster::Private::GetTranslators(BPositionIO* source, + BMessage* ioExtension, uint32 hintType, const char* hintMIME, + uint32 wantType, translator_info** _info, int32* _numInfo) +{ + BAutolock locker(this); + + int32 arraySize = fTranslators.size(); + translator_info* array = new (std::nothrow) translator_info[arraySize]; + if (array == NULL) + return B_NO_MEMORY; + + TranslatorMap::const_iterator iterator = fTranslators.begin(); + int32 count = 0; + + while (iterator != fTranslators.end()) { + BTranslator& translator = *iterator->second.translator; + + status_t status = source->Seek(0, SEEK_SET); + if (status < B_OK) { + delete[] array; + return status; + } + + int32 formatsCount = 0; + const translation_format* formats = translator.InputFormats(&formatsCount); + const translation_format* format = _CheckHints(formats, formatsCount, hintType, + hintMIME); + + translator_info info; + if (translator.Identify(source, format, ioExtension, &info, wantType) == B_OK) { + info.translator = iterator->first; + array[count++] = info; + } + } + + *_info = array; + *_numInfo = count; + qsort(array, count, sizeof(translator_info), BTranslatorRoster::Private::_CompareSupport); + // translators are sorted by best support + + return B_OK; +} + + +status_t +BTranslatorRoster::Private::GetAllTranslators(translator_id** _ids, int32* _count) +{ + BAutolock locker(this); + + int32 arraySize = fTranslators.size(); + translator_id* array = new (std::nothrow) translator_id[arraySize]; + if (array == NULL) + return B_NO_MEMORY; + + TranslatorMap::const_iterator iterator = fTranslators.begin(); + int32 count = 0; + + while (iterator != fTranslators.end()) { + array[count++] = iterator->first; + } + + *_ids = array; + *_count = count; + return B_OK; +} + + +status_t +BTranslatorRoster::Private::GetRefFor(translator_id id, entry_ref& ref) +{ + BAutolock locker(this); + + const translator_item* item = _FindTranslator(id); + if (item == NULL) + return B_NO_TRANSLATOR; + + BEntry entry(&item->ref); + if (entry.InitCheck() == B_OK && entry.Exists() && entry.IsFile()) { + ref = item->ref; + return B_OK; + } + + return B_ERROR; +} + + +void +BTranslatorRoster::Private::TranslatorDeleted(translator_id id) +{ + BAutolock locker(this); + + TranslatorMap::iterator iterator = fTranslators.find(id); + if (iterator == fTranslators.end()) + return; + + fTranslators.erase(iterator); +} + + +/*static*/ int +BTranslatorRoster::Private::_CompareSupport(const void* _a, const void* _b) +{ + const translator_info* infoA = (const translator_info*)_a; + const translator_info* infoB = (const translator_info*)_b; + + float weightA = infoA->quality * infoA->capability; + float weightB = infoB->quality * infoB->capability; + + if (weightA == weightB) + return 0; + if (weightA > weightB) + return -1; + + return 1; +} + + +const translation_format* +BTranslatorRoster::Private::_CheckHints(const translation_format* formats, + int32 formatsCount, uint32 hintType, const char* hintMIME) +{ + if (!formats || formatsCount <= 0 || (!hintType && !hintMIME)) + return NULL; + + // The provided MIME type hint may be a super type + int32 super = 0; + if (hintMIME && !strchr(hintMIME, '/')) + super = strlen(hintMIME); + + // scan for suitable format + for (int32 i = 0; i < formatsCount && formats[i].type; i++) { + if (formats[i].type == hintType + || hintMIME && ((super && !strncmp(formats[i].MIME, hintMIME, super)) + || !strcmp(formats[i].MIME, hintMIME))) + return &formats[i]; + } + + return NULL; +} + + +const translator_item* +BTranslatorRoster::Private::_FindTranslator(translator_id id) const +{ + TranslatorMap::const_iterator iterator = fTranslators.find(id); + if (iterator == fTranslators.end()) + return NULL; + + return &iterator->second; +} + + +const translator_item* +BTranslatorRoster::Private::_FindTranslator(const char* name) const +{ + if (name == NULL) + return NULL; + + TranslatorMap::const_iterator iterator = fTranslators.begin(); + + while (iterator != fTranslators.end()) { + const translator_item& item = iterator->second; + if (item.ref.name != NULL && !strcmp(item.ref.name, name)) + return &item; + + iterator++; + } + + return NULL; +} + + +// #pragma mark - + + +BTranslatorRoster::BTranslatorRoster() +{ + _Initialize(); +} + + +BTranslatorRoster::BTranslatorRoster(BMessage *model) +{ + _Initialize(); + + if (model) { + const char* path; + for (int32 i = 0; model->FindString("be:translator_path", i, &path) == B_OK; i++) { + BEntry entry(path); + entry_ref ref; + if (entry.GetRef(&ref) == B_OK) { + int32 count = 0; + fPrivate->CreateTranslators(ref, count); + } + } + } +} + + +BTranslatorRoster::~BTranslatorRoster() +{ + // If the default BTranslatorRoster is being + // deleted, set the pointer to the default + // BTranslatorRoster to NULL + if (sDefaultRoster == this) + sDefaultRoster = NULL; + + delete fPrivate; +} + + +void +BTranslatorRoster::_Initialize() +{ + fPrivate = new BTranslatorRoster::Private(); +} + + +status_t +BTranslatorRoster::Archive(BMessage* into, bool deep) const +{ + status_t status = BArchivable::Archive(into, deep); + if (status != B_OK) + return status; + + return fPrivate->StoreTranslators(*into); +} + + +BArchivable * +BTranslatorRoster::Instantiate(BMessage* from) +{ + if (!from || !validate_instantiation(from, "BTranslatorRoster")) + return NULL; + + return new BTranslatorRoster(from); +} + + +BTranslatorRoster * +BTranslatorRoster::Default() +{ +// TODO: This code isn't thread safe + // If the default translators have not been loaded, + // create a new BTranslatorRoster for them, and load them. + if (sDefaultRoster == NULL) { + sDefaultRoster = new BTranslatorRoster(); + sDefaultRoster->AddTranslators(NULL); + } + + return sDefaultRoster; +} + + +/*! + This function takes a string of colon delimited paths, and adds + the translators from those paths to this BTranslatorRoster. + + If load_path is NULL, it parses the environment variable + TRANSLATORS. If that does not exist, it uses the system paths: + /boot/home/config/add-ons/Translators, + /system/add-ons/Translators. +*/ +status_t +BTranslatorRoster::AddTranslators(const char* path) +{ + if (path == NULL) + path = getenv("TRANSLATORS"); + if (path == NULL) { + fPrivate->AddDefaultPaths(); + return B_OK; + } + + return fPrivate->AddPaths(path); +} + + +/*! + Adds a BTranslator based object to the BTranslatorRoster. + When you add a BTranslator roster, it is Acquire()'d by + BTranslatorRoster; it is Release()'d when the + BTranslatorRoster is deleted. + + \param translator the translator to be added to the + BTranslatorRoster + + \return B_BAD_VALUE, if translator is NULL, + B_OK if all went well +*/ +status_t +BTranslatorRoster::AddTranslator(BTranslator* translator) +{ + if (!translator) + return B_BAD_VALUE; + + return fPrivate->AddTranslator(translator); +} + + +bool +BTranslatorRoster::IsTranslator(entry_ref* ref) +{ + if (ref == NULL) + return false; + + BPath path(ref); + image_id image = load_add_on(path.Path()); + if (image < B_OK) + return false; + + // Function pointer used to create post R4.5 style translators + BTranslator *(*makeNthTranslator)(int32 n, image_id you, uint32 flags, ...); + + status_t status = get_image_symbol(image, "make_nth_translator", + B_SYMBOL_TYPE_TEXT, (void**)&makeNthTranslator); + if (status < B_OK) { + // If this is a translator add-on, it is in the C format + translator_data translatorData; + status = fPrivate->GetTranslatorData(image, translatorData); + } + + unload_add_on(image); + return status == B_OK; +} + + +/*! + This function determines which translator is best suited + to convert the data from \a source. + + \param source the data to be identified + \param ioExtension the configuration data for the translator + \param _info the information about the chosen translator is put here + \param hintType a hint about the type of data that is in \a source, set + it to zero if the type is not known + \param hintMIME a hint about the MIME type of \a source, set it to NULL + if the type is not known. + \param wantType the desired output type - if zero, any type is okay. + + \return B_OK, identification of \a source was successful, + B_NO_TRANSLATOR, no appropriate translator found, + and other errors from accessing the source stream +*/ +status_t +BTranslatorRoster::Identify(BPositionIO* source, BMessage* ioExtension, + translator_info* _info, uint32 hintType, const char* hintMIME, + uint32 wantType) +{ + if (!source || !_info) + return B_BAD_VALUE; + + return fPrivate->Identify(source, ioExtension, hintType, hintMIME, wantType, _info); +} + + +/*! + Finds all translators capable of handling the data in \a source + and puts them into the outInfo array (which you must delete + yourself when you are done with it). Specifying a value for + \a hintType, \a hintMIME and/or \a wantType causes only the + translators that satisfy them to be included in the outInfo. + + \param source the data to be translated + \param ioExtension the configuration data for the translator + \param _info, the array of acceptable translators is stored here if + the function succeeds. It's the caller's responsibility to free + the array using delete[]. + \param _numInfo, number of entries in the \a _info array + \param hintType a hint about the type of data that is in \a source, set + it to zero if the type is not known + \param hintMIME a hint about the MIME type of \a source, set it to NULL + if the type is not known. + \param wantType the desired output type - if zero, any type is okay. + + \return B_OK, successfully indentified the data in \a source + B_NO_TRANSLATOR, no translator could handle \a source + other errors, problems using \a source +*/ +status_t +BTranslatorRoster::GetTranslators(BPositionIO* source, BMessage* ioExtension, + translator_info** _info, int32* _numInfo, uint32 hintType, + const char* hintMIME, uint32 wantType) +{ + if (source == NULL || _info == NULL || _numInfo == NULL) + return B_BAD_VALUE; + + return fPrivate->GetTranslators(source, ioExtension, hintType, hintMIME, + wantType, _info, _numInfo); +} + + +/*! + Returns an array in \a _ids of all of the translators stored by this + object. + You must free the array using delete[] when you are done with it. + + \param _ids the array is stored there (you own the array). + \param _count number of IDs in the array. +*/ +status_t +BTranslatorRoster::GetAllTranslators(translator_id** _ids, int32* _count) +{ + if (_ids == NULL || _count == NULL) + return B_BAD_VALUE; + + return fPrivate->GetAllTranslators(_ids, _count); +} + + +/*! + Returns information about the translator with the specified + translator \a id. + You must not free any of the data you get back. + + \param id identifies which translator you want info for + \param _name the translator name is put here + \param _info the translator description is put here + \param _version the translation version is put here + + \return B_OK if successful, + B_BAD_VALUE, if all parameters are NULL + B_NO_TRANSLATOR, \id didn't identify an existing translator +*/ +status_t +BTranslatorRoster::GetTranslatorInfo(translator_id id, const char** _name, + const char** _info, int32* _version) +{ + if (_name == NULL && _info == NULL && _version == NULL) + return B_BAD_VALUE; + + BAutolock locker(fPrivate); + + BTranslator* translator = fPrivate->FindTranslator(id); + if (translator == NULL) + return B_NO_TRANSLATOR; + + if (_name) + *_name = translator->TranslatorName(); + if (_info) + *_info = translator->TranslatorInfo(); + if (_version) + *_version = translator->TranslatorVersion(); + + return B_OK; +} + + +/*! + Returns all of the input formats for the translator specified + by \a id. + You must not free any of the data you get back. + + \param id identifies which translator you want the input formats for + \param _formats array of input formats + \param _numFormats number of formats in the array + + \return B_OK if successful, + B_BAD_VALUE, if any parameter is NULL + B_NO_TRANSLATOR, \id didn't identify an existing translator +*/ +status_t +BTranslatorRoster::GetInputFormats(translator_id id, + const translation_format** _formats, int32* _numFormats) +{ + if (_formats == NULL || _numFormats == NULL) + return B_BAD_VALUE; + + BAutolock locker(fPrivate); + + BTranslator* translator = fPrivate->FindTranslator(id); + if (translator == NULL) + return B_NO_TRANSLATOR; + + *_formats = translator->InputFormats(_numFormats); + return B_OK; +} + + +/*! + Returns all of the output formats for the translator specified + by \a id. + You must not free any of the data you get back. + + \param id identifies which translator you want the output formats for + \param _formats array of output formats + \param _numFormats number of formats in the array + + \return B_OK if successful, + B_BAD_VALUE, if any parameter is NULL + B_NO_TRANSLATOR, \id didn't identify an existing translator +*/ +status_t +BTranslatorRoster::GetOutputFormats(translator_id id, + const translation_format** _formats, int32* _numFormats) +{ + if (_formats == NULL || _numFormats == NULL) + return B_BAD_VALUE; + + BAutolock locker(fPrivate); + + BTranslator* translator = fPrivate->FindTranslator(id); + if (translator == NULL) + return B_NO_TRANSLATOR; + + *_formats = translator->OutputFormats(_numFormats); + return B_OK; +} + + +/*! + This function is the whole point of the Translation Kit. + This is for translating the data in \a source to \a destination + using the format \a wantOutType. + + \param source the data to be translated + \param ioExtension the configuration data for the translator + \param info information about translator to use (can be NULL, in which + case the \a source is identified first) + \param destination where \a source is translated to + \param hintType a hint about the type of data that is in \a source, set + it to zero if the type is not known + \param hintMIME a hint about the MIME type of \a source, set it to NULL + if the type is not known. + \param wantType the desired output type - if zero, any type is okay. + + \return B_OK, translation of \a source was successful, + B_NO_TRANSLATOR, no appropriate translator found, + and other errors from accessing the source and destination streams +*/ +status_t +BTranslatorRoster::Translate(BPositionIO* source, const translator_info* info, + BMessage* ioExtension, BPositionIO* destination, uint32 wantOutType, + uint32 hintType, const char* hintMIME) +{ + if (source == NULL || destination == NULL) + return B_BAD_VALUE; + + translator_info infoBuffer; + + if (info == NULL) { + // look for a suitable translator + status_t status = Identify(source, ioExtension, &infoBuffer, + hintType, hintMIME, wantOutType); + if (status < B_OK) + return status; + + info = &infoBuffer; + } + + if (!fPrivate->Lock()) + return B_ERROR; + + BTranslator* translator = fPrivate->FindTranslator(info->translator); + if (translator != NULL) { + translator->Acquire(); + // make sure this translator is not removed while we're playing with it; + // translating shouldn't be serialized! + } + + fPrivate->Unlock(); + + if (translator == NULL) + return B_NO_TRANSLATOR; + + status_t status = source->Seek(0, SEEK_SET); + if (status == B_OK) { + status = translator->Translate(source, info, ioExtension, wantOutType, + destination); + } + translator->Release(); + + return status; +} + + +/*! + This function is the whole point of the Translation Kit. + This is for translating the data in \a source to \a destination + using the format \a wantOutType and the translator identified + by \a id. + + \param id the translator to be used + \param source the data to be translated + \param ioExtension the configuration data for the translator + \param destination where \a source is translated to + \param wantType the desired output type - if zero, any type is okay. + + \return B_OK, translation of \a source was successful, + B_NO_TRANSLATOR, no appropriate translator found, + and other errors from accessing the source and destination streams +*/ +status_t +BTranslatorRoster::Translate(translator_id id, BPositionIO* source, + BMessage* ioExtension, BPositionIO* destination, uint32 wantOutType) +{ + if (source == NULL || destination == NULL) + return B_BAD_VALUE; + + BTranslator* translator = fPrivate->FindTranslator(id); + if (translator != NULL) { + translator->Acquire(); + // make sure this translator is not removed while we're playing with it; + // translating shouldn't be serialized! + } + + fPrivate->Unlock(); + + if (translator == NULL) + return B_NO_TRANSLATOR; + + status_t status = source->Seek(0, SEEK_SET); + if (status == B_OK) { + translator_info info; + status = translator->Identify(source, NULL, ioExtension, &info, wantOutType); + if (status >= B_OK) { + status = translator->Translate(source, &info, ioExtension, wantOutType, + destination); + } + } + translator->Release(); + + return status; +} + + +/*! + Creates a BView in \a _view for configuring the translator specified + by \a id. Not all translators support this, though. + + \param id identifies which translator you want the input formats for + \param ioExtension the configuration data for the translator + \param _view the view for configuring the translator + \param _extent the bounds for the (resizable) view + + \return B_OK if successful, + B_BAD_VALUE, if any parameter is NULL + B_NO_TRANSLATOR, \id didn't identify an existing translator +*/ +status_t +BTranslatorRoster::MakeConfigurationView(translator_id id, BMessage* ioExtension, + BView** _view, BRect* _extent) +{ + if (_view == NULL || _extent == NULL) + return B_BAD_VALUE; + + BAutolock locker(fPrivate); + + BTranslator* translator = fPrivate->FindTranslator(id); + if (translator == NULL) + return B_NO_TRANSLATOR; + + return translator->MakeConfigurationView(ioExtension, _view, _extent); +} + + +/*! + Gets the configuration setttings for the translator + specified by \a id and puts them into \a ioExtension. + + \param id identifies which translator you want the input formats for + \param ioExtension the configuration data for the translator + + \return B_OK if successful, + B_BAD_VALUE, if \a ioExtension is NULL + B_NO_TRANSLATOR, \id didn't identify an existing translator +*/ +status_t +BTranslatorRoster::GetConfigurationMessage(translator_id id, BMessage* ioExtension) +{ + if (!ioExtension) + return B_BAD_VALUE; + + BAutolock locker(fPrivate); + + BTranslator* translator = fPrivate->FindTranslator(id); + if (translator == NULL) + return B_NO_TRANSLATOR; + + return translator->GetConfigurationMessage(ioExtension); +} + + +/*! + Gets the entry_ref for the given translator (of course, this works only + for disk based translators). + + \param id identifies which translator you want the input formats for + \param ref the entry ref is stored there + + \return B_OK if successful, + B_ERROR, if this is not a disk based translator + B_BAD_VALUE, if \a ref is NULL + B_NO_TRANSLATOR, \id didn't identify an existing translator +*/ +status_t +BTranslatorRoster::GetRefFor(translator_id id, entry_ref* ref) +{ + if (ref == NULL) + return B_BAD_VALUE; + + return fPrivate->GetRefFor(id, *ref); +} + + +status_t +BTranslatorRoster::StartWatching(BMessenger target) +{ + return fPrivate->StartWatching(target); +} + + +status_t +BTranslatorRoster::StopWatching(BMessenger target) +{ + return fPrivate->StopWatching(target); +} + + +// #pragma mark - private + + +BTranslatorRoster::BTranslatorRoster(const BTranslatorRoster &other) +{ +} + + BTranslatorRoster & BTranslatorRoster::operator=(const BTranslatorRoster &tr) { return *this; } -// --------------------------------------------------------------- -// Constructor -// -// Initilizes the BTranslatorRoster to the empty state, it loads -// no translators. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -BTranslatorRoster::BTranslatorRoster() : BArchivable() -{ - Initialize(); -} -// --------------------------------------------------------------- -// Constructor -// -// This constructor initilizes the BTranslatorRoster, then -// loads all of the translators specified in the -// "be:translator_path" field of the supplied BMessage. -// -// Preconditions: -// -// Parameters: model, the BMessage where the translator paths are -// found. -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -BTranslatorRoster::BTranslatorRoster(BMessage *model) : BArchivable() -{ - Initialize(); - - if (model) { - BString bstr; - for (int32 i = 0; - model->FindString("be:translator_path", i, &bstr) == B_OK; i++) { - AddTranslators(bstr.String()); - bstr = ""; - } - } -} - -// --------------------------------------------------------------- -// Initialize() -// -// This function initializes this object to the empty state. It -// is used by all constructors. -// -// Preconditions: Object must be in initial uninitialized state -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void BTranslatorRoster::Initialize() -{ - fpTranslators = fpLastTranslator = NULL; - fSem = create_sem(1, "BTranslatorRoster Lock"); -} - -// --------------------------------------------------------------- -// Destructor -// -// Unloads any translators that were loaded and frees all memory -// allocated by the BTranslatorRoster, except for the static -// member data. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -BTranslatorRoster::~BTranslatorRoster() -{ - if (fSem > 0 && acquire_sem(fSem) == B_NO_ERROR) { - - // If the default BTranslatorRoster is being - // deleted, set the pointer to the default - // BTranslatorRoster to NULL - if (fspDefaultTranslators == this) - fspDefaultTranslators = NULL; - - // FIRST PASS: release BTranslator objects - translator_node *pTranNode = fpTranslators; - while (pTranNode) { - translator_node *pRelTranNode = pTranNode; - pTranNode = pTranNode->next; - pRelTranNode->translator->Release(); - } - - // SECOND PASS: unload images and delete nodes - // (I can't delete a BTranslator if I've deleted - // the code for it) - pTranNode = fpTranslators; - while (pTranNode) { - translator_node *pDelTranNode = pTranNode; - pTranNode = pTranNode->next; - - // only try to unload actual images - if (pDelTranNode->image >= 0) - unload_add_on(pDelTranNode->image); - // I may end up trying to unload the same image - // more than once, but I don't think - // that should be a problem - delete[] pDelTranNode->path; - delete pDelTranNode; - } - - fpTranslators = fpLastTranslator = NULL; - } - - delete_sem(fSem); -} - -// --------------------------------------------------------------- -// Archive -// -// Archives the BTranslatorRoster by recording its loaded add-ons -// in the BMessage into. The deep variable appeared to have no -// impact in Be's version of this function, so I went the same -// route. -// -// Preconditions: -// -// Parameters: into, the BMessage that this object is written to -// deep, if true, more data is written, if false, -// less data is written -// -// Postconditions: -// -// Returns: B_OK, if everything went well -// B_BAD_VALUE, if into is NULL -// B_NOT_INITIALIZED, if the constructor couldn't create -// a semaphore -// other errors that BMessage::AddString() and -// BArchivable::Archive() return -// --------------------------------------------------------------- -status_t -BTranslatorRoster::Archive(BMessage *into, bool deep) const -{ - if (!into) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - result = BArchivable::Archive(into, deep); - if (result == B_OK) { - result = into->AddString("class", "BTranslatorRoster"); - - translator_node *pTranNode = NULL; - for (pTranNode = fpTranslators; result == B_OK && pTranNode; - pTranNode = pTranNode->next) { - if (pTranNode->path[0]) - result = into->AddString("be:translator_path", - pTranNode->path); - } - } - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// Instantiate -// -// This static member function returns a new BTranslatorRosters -// object, allocated by new and created with the version of the -// constructor that takes a BMessage archive. However if the -// archive doesn't contain data for a BTranslatorRoster object, -// Instantiate() returns NULL. -// -// Preconditions: -// -// Parameters: from, the BMessage to create the new object from -// -// Postconditions: -// -// Returns: returns NULL if the BMessage was no good -// returns a BArchivable * to a BTranslatorRoster -// --------------------------------------------------------------- -BArchivable * -BTranslatorRoster::Instantiate(BMessage *from) -{ - if (!from || !validate_instantiation(from, "BTranslatorRoster")) - return NULL; - else - return new BTranslatorRoster(from); -} - -// --------------------------------------------------------------- -// Version -// -// Sets outCurVersion to the Translation Kit protocol version -// number and outMinVersion to the minimum protocol version number -// supported. Returns a string containing verbose version -// information. Currently, inAppVersion must be -// B_TRANSLATION_CURRENT_VERSION, but as far as I can tell, its -// completely ignored. -// -// Preconditions: -// -// Parameters: outCurVersion, the current version is stored here -// outMinVersion, the minimum supported version is -// stored here -// inAppVersion, is ignored as far as I know -// -// Postconditions: -// -// Returns: string of verbose translation kit version -// information or an empty string if either of the -// out variables is NULL. -// --------------------------------------------------------------- const char * -BTranslatorRoster::Version(int32 *outCurVersion, int32 *outMinVersion, +Version__17BTranslatorRosterPlT1l(int32 *outCurVersion, int32 *outMinVersion, int32 inAppVersion) { if (!outCurVersion || !outMinVersion) @@ -340,1390 +1179,10 @@ BTranslatorRoster::Version(int32 *outCurVersion, int32 *outMinVersion, return vString; } -// --------------------------------------------------------------- -// Default -// -// This static member function returns a pointer to the default -// BTranslatorRoster that has the default translators stored in -// it. The paths for the default translators are loaded from -// the TRANSLATORS environment variable. If it does not exist, -// the paths used are /boot/home/config/add-ons/Translators, -// /boot/home/config/add-ons/Datatypes, and -// /system/add-ons/Translators. The BTranslatorRoster returned -// by this function is global to the application and should -// not be deleted. -// -// This code probably isn't thread safe (yet). -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: pointer to the default BTranslatorRoster -// --------------------------------------------------------------- -BTranslatorRoster * -BTranslatorRoster::Default() -{ - // If the default translators have not been loaded, - // create a new BTranslatorRoster for them, and load them. - if (!fspDefaultTranslators) { - fspDefaultTranslators = new BTranslatorRoster(); - fspDefaultTranslators->AddTranslators(NULL); - } - - return fspDefaultTranslators; -} - -// --------------------------------------------------------------- -// AddTranslators -// -// This function takes a string of colon delimited paths, -// (folders or specific files) and adds the translators from -// those paths to this BTranslatorRoster. -// -// If load_path is NULL, it parses the environment variable -// TRANSLATORS. If that does not exist, it uses the paths: -// /boot/home/config/add-ons/Translators, -// /boot/home/config/add-ons/Datatypes and -// /system/add-ons/Translators. -// -// Preconditions: -// -// Parameters: load_path, colon delimited list of paths -// to load translators from -// -// Postconditions: -// -// Returns: B_OK on success, -// B_BAD_VALUE if there was something wrong with -// load_path -// other errors for problems with loading add-ons -// --------------------------------------------------------------- -status_t -BTranslatorRoster::AddTranslators(const char *load_path) -{ - if (fSem <= 0) - return fSem; - - status_t loadErr = B_ERROR; - int32 nLoaded = 0; - - if (acquire_sem(fSem) == B_OK) { - if (load_path == NULL) - load_path = getenv("TRANSLATORS"); - if (load_path == NULL) - load_path = kgDefaultTranslatorPath; - - char pathbuf[PATH_MAX]; - const char *ptr = load_path; - const char *end = ptr; - struct stat stbuf; - while (*ptr != 0) { - // find segments specified by colons - end = strchr(ptr, ':'); - if (end == NULL) - end = ptr + strlen(ptr); - if (end-ptr > PATH_MAX - 1) - loadErr = B_BAD_VALUE; - else { - // copy this segment of the path into a path, and load it - memcpy(pathbuf, ptr, end - ptr); - pathbuf[end - ptr] = 0; - - if (!stat(pathbuf, &stbuf)) { - // files are loaded as translators - if (S_ISREG(stbuf.st_mode)) { - status_t err = LoadTranslator(pathbuf); - if (err != B_OK) - loadErr = err; - else - nLoaded++; - } else - // directories are scanned - LoadDir(pathbuf, loadErr, nLoaded); - } - } - ptr = end + 1; - if (*end == 0) - break; - } // while (*ptr != 0) - - release_sem(fSem); - - } // if (acquire_sem(fSem) == B_OK) - - // if anything loaded, it's not too bad - if (nLoaded) - loadErr = B_OK; - - return loadErr; -} - -// --------------------------------------------------------------- -// AddTranslator -// -// Adds a BTranslator based object to the BTranslatorRoster. -// When you add a BTranslator roster, it is Acquire()'d by -// BTranslatorRoster; it is Release()'d when the -// BTranslatorRoster is deleted. -// -// Preconditions: -// -// Parameters: translator, the translator to be added to the -// BTranslatorRoster -// -// Postconditions: -// -// Returns: B_BAD_VALUE, if translator is NULL, -// B_NOT_INITIALIZED, if the constructor couldn't -// create a semaphore -// B_OK if all went well -// --------------------------------------------------------------- -status_t -BTranslatorRoster::AddTranslator(BTranslator *translator) -{ - if (!translator) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_NO_ERROR) { - // Add the translator to the list even if - // it is already in the list - result = AddTranslatorToList(translator); - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// Identify -// -// This function determines which translator is best suited -// to convert the data from inSource. -// -// Preconditions: -// -// Parameters: inSource, the data to be translated, -// ioExtension, the configuration data for the -// translator -// outInfo, the information about the chosen -// translator is put here -// inHintType, a hint about the type of data -// that is in inSource, can be -// zero if type is not known -// inHintMIME, a hint about the MIME type of -// data that is in inSource, -// can be NULL -// inWantType, the desired output type for -// inSource, if zero, any type -// is ok. -// -// Postconditions: -// -// Returns: B_OK, identification of inSource was successful, -// B_NO_TRANSLATOR, no appropriate translator found -// B_NOT_INITIALIZED, the constructor failed to -// create a semaphore -// B_BAD_VALUE, inSource or outInfo is NULL -// other values, error using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::Identify(BPositionIO *inSource, - BMessage *ioExtension, translator_info *outInfo, - uint32 inHintType, const char *inHintMIME, - uint32 inWantType) -{ - if (!inSource || !outInfo) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - bool bFoundMatch = false; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - - translator_node *pTranNode = fpTranslators; - float bestWeight = 0.0; - for (; pTranNode; pTranNode = pTranNode->next) { - - const translation_format *format = NULL; - translator_info tmpInfo; - float weight = 0.0; - bool addmatch = false; - // eliminates need for a goto - - result = inSource->Seek(0, SEEK_SET); - if (result == B_OK) { - - int32 inputFormatsCount = 0; - const translation_format *inputFormats = - pTranNode->translator->InputFormats(&inputFormatsCount); - - if (CheckFormats(inputFormats, inputFormatsCount, inHintType, - inHintMIME, &format)) { - - // after checking the formats for hints, we still need to make - // sure the translator recognizes the data and can output the - // desired format, so we call its' Identify() function. - if (format && !pTranNode->translator->Identify(inSource, - format, ioExtension, &tmpInfo, inWantType)) - addmatch = true; - - } else if (!pTranNode->translator->Identify(inSource, NULL, - ioExtension, &tmpInfo, inWantType)) - addmatch = true; - - if (addmatch) { - weight = tmpInfo.quality * tmpInfo.capability; - if (weight > bestWeight) { - bFoundMatch = true; - bestWeight = weight; - - tmpInfo.translator = pTranNode->id; - outInfo->type = tmpInfo.type; - outInfo->translator = tmpInfo.translator; - outInfo->group = tmpInfo.group; - outInfo->quality = tmpInfo.quality; - outInfo->capability = tmpInfo.capability; - strcpy(outInfo->name, tmpInfo.name); - strcpy(outInfo->MIME, tmpInfo.MIME); - } - } - } // if (result == B_OK) - } // for (; pTranNode; pTranNode = pTranNode->next) - - if (bFoundMatch) - result = B_NO_ERROR; - else if (result == B_OK) - result = B_NO_TRANSLATOR; - - release_sem(fSem); - } // if (acquire_sem(fSem) == B_OK) - - return result; -} - -// --------------------------------------------------------------- -// compare_data -// -// This function is not a member of BTranslatorRoster, but it is -// used by the GetTranslators() member function as the function -// passed to qsort to sort the translators from best to worst. -// -// Preconditions: -// -// Parameters: a, pointer to translator_info structure to be -// compared to b -// b, pointer to translator_info structure to be -// compared to a -// -// Postconditions: -// -// Returns: -// NOTE: Since qsort sorts lowest to highest, and I want -// the highest quality/capability first, I must do things -// "backwards." -// -// 0 if A and B are equally capable -// -1 if A is more capable than B -// 1 if A is less capable than B -// --------------------------------------------------------------- -static int -compare_data(const void *a, const void *b) -{ - register const translator_info *ai = - reinterpret_cast (a); - - register const translator_info *bi = - reinterpret_cast (b); - - float acmp, bcmp; - acmp = ai->quality * ai->capability; - bcmp = bi->quality * bi->capability; - if (acmp == bcmp) - return 0; - else if (acmp > bcmp) - return -1; - else - return 1; -} - -// --------------------------------------------------------------- -// GetTranslators -// -// Finds all translators capable of handling the data in inSource -// and puts them into the outInfo array (which you must delete -// yourself when you are done with it). Specifying a value for -// inHintType, inHintMIME and/or inWantType causes only the -// translators that satisfy them to be included in the outInfo. -// -// Preconditions: -// -// Parameters: inSource, the data that wants to be translated -// ioExtension, configuration data for the translator -// outInfo, the array of acceptable translators is -// stored here if the function succeeds -// outNumInfo, number of entries in outInfo -// inHintType, hint for the type of data in -// inSource, can be zero if the -// type is not known -// inHintMIME, hint MIME type of the data -// in inSource, can be NULL if -// the MIME type is not known -// inWantType, the desired output type for -// the data in inSource, can be zero -// for any type. -// -// Postconditions: -// -// Returns: B_OK, successfully indentified the data in inSource -// B_NO_TRANSLATOR, no translator could handle inSource -// B_NOT_INITIALIZED, the constructore failed to create -// a semaphore -// B_BAD_VALUE, inSource, outInfo, or outNumInfo is NULL -// other errors, problems using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetTranslators(BPositionIO *inSource, - BMessage *ioExtension, translator_info **outInfo, - int32 *outNumInfo, uint32 inHintType, - const char *inHintMIME, uint32 inWantType) -{ - if (!inSource || !outInfo || !outNumInfo) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - *outInfo = NULL; - *outNumInfo = 0; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - - int32 physCnt = 10; - *outInfo = new translator_info[physCnt]; - *outNumInfo = 0; - - translator_node *pTranNode = fpTranslators; - for (; pTranNode; pTranNode = pTranNode->next) { - - const translation_format *format = NULL; - translator_info tmpInfo; - bool addmatch = false; - // avoid the need for a goto - - result = inSource->Seek(0, SEEK_SET); - if (result < B_OK) { - // break out of the loop if error reading from source - delete *outInfo; - *outInfo = NULL; - break; - } else { - int32 inputFormatsCount = 0; - const translation_format *inputFormats = - pTranNode->translator->InputFormats(&inputFormatsCount); - - if (CheckFormats(inputFormats, inputFormatsCount, inHintType, - inHintMIME, &format)) { - if (format && !pTranNode->translator->Identify(inSource, - format, ioExtension, &tmpInfo, inWantType)) - addmatch = true; - - } else if (!pTranNode->translator->Identify(inSource, NULL, - ioExtension, &tmpInfo, inWantType)) - addmatch = true; - - if (addmatch) { - // dynamically resize output list - // - if (physCnt <= *outNumInfo) { - physCnt += 10; - translator_info *nOut = new translator_info[physCnt]; - for (int ix = 0; ix < *outNumInfo; ix++) - nOut[ix] = (*outInfo)[ix]; - - delete[] *outInfo; - *outInfo = nOut; - } - - // XOR to discourage taking advantage of undocumented - // features - tmpInfo.translator = pTranNode->id; - (*outInfo)[(*outNumInfo)++] = tmpInfo; - } - } - } // for (; pTranNode; pTranNode = pTranNode->next) - - // if exited loop WITHOUT errors - if (!pTranNode) { - - if (*outNumInfo > 1) - qsort(*outInfo, *outNumInfo, sizeof(**outInfo), compare_data); - - if (*outNumInfo > 0) - result = B_NO_ERROR; - else - result = B_NO_TRANSLATOR; - } - - release_sem(fSem); - - } // if (acquire_sem(fSem) == B_OK) - - return result; -} - -// --------------------------------------------------------------- -// GetAllTranslators -// -// Returns a list of all of the translators stored by this object. -// You must delete the list, outList, yourself when you are done -// with it. -// -// Preconditions: -// -// Parameters: outList, where the list is stored, -// (you must delete the list yourself) -// outCount, where the count of the items in -// the list is stored -// -// Postconditions: -// -// Returns: B_BAD_VALUE, if outList or outCount is NULL -// B_NOT_INITIALIZED, if the constructor couldn't -// create a semaphore -// B_NO_ERROR, if successful -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetAllTranslators( - translator_id **outList, int32 *outCount) -{ - if (!outList || !outCount) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - *outList = NULL; - *outCount = 0; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - // count translators - translator_node *pTranNode = NULL; - for (pTranNode = fpTranslators; pTranNode; pTranNode = pTranNode->next) - (*outCount)++; - // populate the outList - *outList = new translator_id[*outCount]; - int32 i = 0; - for (pTranNode = fpTranslators; pTranNode; pTranNode = pTranNode->next) - (*outList)[i++] = pTranNode->id; - - result = B_NO_ERROR; - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// GetTranslatorInfo -// -// Returns information about the translator with translator_id -// forTranslator. outName is the short name of the translator, -// outInfo is the verbose name / description of the translator, -// and outVersion is the integer representation of the translator -// version. -// -// Preconditions: -// -// Parameters: forTranslator, identifies which translator -// you want info for -// outName, the translator name is put here -// outInfo, the translator info is put here -// outVersion, the translation version is put here -// -// Postconditions: -// -// Returns: B_NO_ERROR, if successful, -// B_BAD_VALUE, if any parameter is NULL -// B_NOT_INITIALIZED, if the constructor couldn't -// create a semaphore -// B_NO_TRANSLATOR, if forTranslator is not a valid -// translator id -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetTranslatorInfo( - translator_id forTranslator, const char **outName, - const char **outInfo, int32 *outVersion) -{ - if (!outName || !outInfo || !outVersion) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - // find the translator we've requested - translator_node *pTranNode = FindTranslatorNode(forTranslator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else { - *outName = pTranNode->translator->TranslatorName(); - *outInfo = pTranNode->translator->TranslatorInfo(); - *outVersion = pTranNode->translator->TranslatorVersion(); - - result = B_NO_ERROR; - } - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// GetInputFormats -// -// Returns all of the input formats for the translator -// forTranslator. Not all translators publish the input formats -// that they accept. -// -// Preconditions: -// -// Parameters: forTranslator, identifies which translator -// you want info for -// outFormats, array of input formats -// outNumFormats, number of items in outFormats -// -// Postconditions: -// -// Returns: B_NO_ERROR, if successful -// B_BAD_VALUE, if either pointer is NULL -// B_NOT_INITIALIZED, if the constructor couldn't -// create a semaphore -// B_NO_TRANSLATOR, if forTranslator is a bad id -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetInputFormats(translator_id forTranslator, - const translation_format **outFormats, int32 *outNumFormats) -{ - if (!outFormats || !outNumFormats) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - *outFormats = NULL; - *outNumFormats = 0; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - // find the translator we've requested - translator_node *pTranNode = FindTranslatorNode(forTranslator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else { - *outFormats = pTranNode->translator->InputFormats(outNumFormats); - result = B_NO_ERROR; - } - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// GetOutputFormats -// -// Returns all of the output formats for the translator -// forTranslator. Not all translators publish the output formats -// that they accept. -// -// Preconditions: -// -// Parameters: forTranslator, identifies which translator -// you want info for -// outFormats, array of output formats -// outNumFormats, number of items in outFormats -// -// Postconditions: -// -// Returns: B_NO_ERROR, if successful -// B_BAD_VALUE, if either pointer is NULL -// B_NOT_INITIALIZED, if the constructor couldn't -// create a semaphore -// B_NO_TRANSLATOR, if forTranslator is a bad id -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetOutputFormats(translator_id forTranslator, - const translation_format **outFormats, int32 *outNumFormats) -{ - if (!outFormats || !outNumFormats) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - *outFormats = NULL; - *outNumFormats = 0; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - // find the translator we've requested - translator_node *pTranNode = FindTranslatorNode(forTranslator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else { - *outFormats = pTranNode->translator->OutputFormats(outNumFormats); - result = B_NO_ERROR; - } - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// Translate -// -// This function is the whole point of the Translation Kit. -// This is for translating the data in inSource to outDestination -// using the format inWantOutType. -// -// Preconditions: -// -// Parameters: inSource, the data that wants to be translated -// ioExtension, configuration data for the translator -// inInfo, identifies the translator to use, can be -// NULL, calls Identify() if NULL -// inHintType, hint for the type of data in -// inSource, can be zero if the -// type is not known -// inHintMIME, hint MIME type of the data -// in inSource, can be NULL if -// the MIME type is not known -// inWantOutType, the desired output type for -// the data in inSource. -// outDestination, where inSource is translated to -// -// Postconditions: -// -// Returns: B_OK, translation successful, -// B_NO_TRANSLATOR, no appropriate translator found -// B_NOT_INITIALIZED, the constructor failed to -// create a semaphore -// B_BAD_VALUE, inSource or outDestination is NULL -// other values, error using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::Translate(BPositionIO *inSource, - const translator_info *inInfo, BMessage *ioExtension, - BPositionIO *outDestination, uint32 inWantOutType, - uint32 inHintType, const char *inHintMIME) -{ - if (!inSource || !outDestination) - return B_BAD_VALUE; - - if (fSem <= 0) - return B_NOT_INITIALIZED; - - status_t result = B_OK; - translator_info stat_info; - - if (!inInfo) { - // go look for a suitable translator - inInfo = &stat_info; - - result = Identify(inSource, ioExtension, &stat_info, - inHintType, inHintMIME, inWantOutType); - // Identify is a locked function, so it cannot be - // called from code that is already locked - } - - if (result >= B_OK && acquire_sem(fSem) == B_OK) { - translator_node *pTranNode = FindTranslatorNode(inInfo->translator); - if (!pTranNode) { - result = B_NO_TRANSLATOR; - } - else { - result = inSource->Seek(0, SEEK_SET); - if (result == B_OK) - result = pTranNode->translator->Translate(inSource, inInfo, - ioExtension, inWantOutType, outDestination); - } - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// Translate -// -// This function is the whole point of the Translation Kit. -// This is for translating the data in inSource to outDestination -// using the format inWantOutType. -// -// Preconditions: -// -// Parameters: inSource, the data that wants to be translated -// ioExtension, configuration data for the translator -// inTranslator, the translator to use for the -// translation -// inWantOutType, the desired output type for -// the data in inSource. -// outDestination, where inSource is translated to -// -// Postconditions: -// -// Returns: B_OK, translation successful, -// B_NO_TRANSLATOR, inTranslator is an invalid id -// B_NOT_INITIALIZED, the constructor failed to -// create a semaphore -// B_BAD_VALUE, inSource or outDestination is NULL -// other values, error using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::Translate(translator_id inTranslator, - BPositionIO *inSource, BMessage *ioExtension, - BPositionIO *outDestination, uint32 inWantOutType) -{ - if (!inSource || !outDestination) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - translator_node *pTranNode = FindTranslatorNode(inTranslator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else { - result = inSource->Seek(0, SEEK_SET); - if (result == B_OK) { - translator_info traninfo; - result = pTranNode->translator->Identify(inSource, NULL, - ioExtension, &traninfo, inWantOutType); - if (result == B_OK) { - result = inSource->Seek(0, SEEK_SET); - if (result == B_OK) { - result = pTranNode->translator->Translate(inSource, - &traninfo, ioExtension, inWantOutType, - outDestination); - } - } - } - } - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// MakeConfigurationView -// -// Returns outView, a BView for configuring the translator -// forTranslator. Not all translators support this. -// -// Preconditions: -// -// Parameters: forTranslator, the translator the view is for -// ioExtension, the configuration data for -// the translator -// outView, the view for configuring the -// translator -// outExtent, the bounds for the view, the view -// can be resized -// -// Postconditions: -// -// Returns: B_OK, success, -// B_NO_TRANSLATOR, inTranslator is an invalid id -// B_NOT_INITIALIZED, the constructor failed to -// create a semaphore -// B_BAD_VALUE, inSource or outDestination is NULL -// other values, error using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::MakeConfigurationView( - translator_id forTranslator, BMessage *ioExtension, - BView **outView, BRect *outExtent) -{ - if (!outView || !outExtent) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - translator_node *pTranNode = FindTranslatorNode(forTranslator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else - result = pTranNode->translator->MakeConfigurationView(ioExtension, - outView, outExtent); - - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// GetConfigurationMessage -// -// Gets the configuration setttings for the translator -// forTranslator and puts the settings into ioExtension. -// -// Preconditions: -// -// Parameters: forTranslator, the translator the info -// is for -// ioExtension, the configuration data for -// the translator is stored here -// -// Postconditions: -// -// Returns: B_OK, success, -// B_NO_TRANSLATOR, inTranslator is an invalid id -// B_NOT_INITIALIZED, the constructor failed to -// create a semaphore -// B_BAD_VALUE, inSource or outDestination is NULL -// other values, error using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetConfigurationMessage( - translator_id forTranslator, BMessage *ioExtension) -{ - if (!ioExtension) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - translator_node *pTranNode = FindTranslatorNode(forTranslator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else - result = - pTranNode->translator->GetConfigurationMessage(ioExtension); - - release_sem(fSem); - } - - return result; -} - -// --------------------------------------------------------------- -// GetRefFor -// -// Gets the entry_ref for the given translator. -// -// Preconditions: -// -// Parameters: forTranslator, the translator the info -// is for -// entry_ref, where the entry ref is stored -// -// Postconditions: -// -// Returns: B_OK, success, -// B_NO_TRANSLATOR, translator is an invalid id -// B_NOT_INITIALIZED, the constructor failed to -// create a semaphore -// B_BAD_VALUE, inSource or outDestination is NULL -// other values, error using inSource -// --------------------------------------------------------------- -status_t -BTranslatorRoster::GetRefFor(translator_id translator, - entry_ref *out_ref) -{ - if (!out_ref) - return B_BAD_VALUE; - - status_t result = B_NOT_INITIALIZED; - - if (fSem > 0 && acquire_sem(fSem) == B_OK) { - translator_node *pTranNode = FindTranslatorNode(translator); - if (!pTranNode) - result = B_NO_TRANSLATOR; - else { - if (pTranNode->path[0] == '\0') - result = B_ERROR; - else - result = get_ref_for_path(pTranNode->path, out_ref); - } - release_sem(fSem); - } - - return result; -} - - -// --------------------------------------------------------------- -// FindTranslatorNode -// -// Finds the translator_node that holds the translator with -// the translator_id id. -// -// Preconditions: -// -// Parameters: id, the translator you want a translator_node for -// -// Postconditions: -// -// Returns: NULL if id is not a valid translator_id, -// pointer to the translator_node that holds the -// translator id -// --------------------------------------------------------------- -translator_node * -BTranslatorRoster::FindTranslatorNode(translator_id id) -{ - translator_node *pTranNode = NULL; - for (pTranNode = fpTranslators; pTranNode; pTranNode = pTranNode->next) - if (pTranNode->id == id) - break; - - return pTranNode; -} - -const char * -get_file_name(const char *path) -{ - const char *file_name = strrchr(path, '/'); - if (file_name) - file_name++; - else - file_name = path; - - return file_name; -} - -// --------------------------------------------------------------- -// LoadTranslator -// -// Loads the translator from path into memory and adds it to -// the BTranslatorRoster. -// -// Preconditions: This should only be called inside of locked -// code. -// -// Parameters: path, the path for the translator to be loaded -// -// Postconditions: -// -// Returns: B_BAD_VALUE, if path is NULL, -// B_NO_ERROR, if all is well, -// other values if error loading add ons -// --------------------------------------------------------------- -status_t -BTranslatorRoster::LoadTranslator(const char *path) -{ - if (!path) - return B_BAD_VALUE; - - // check that this ref is not already loaded - const char *file_name = get_file_name(path); - - // If a translator with the same filename has already - // been loaded, do not load the current translator and - // return no error. This code is not fool proof, however. - for (translator_node *i = fpTranslators; i; i = i->next) - if (!strcmp(file_name, get_file_name(i->path))) - return B_NO_ERROR; - - image_id image = load_add_on(path); - // Load the data and code for the Translator into memory - if (image < 0) - return image; - - // Function pointer used to create post R4.5 style translators - BTranslator *(*pMakeNthTranslator)(int32 n, image_id you, uint32 flags, ...); - - status_t err = get_image_symbol(image, "make_nth_translator", - B_SYMBOL_TYPE_TEXT, reinterpret_cast (&pMakeNthTranslator)); - if (!err) { - // If the translator add-on supports the post R4.5 - // translator creation mechanism, keep loading translators - // until MakeNthTranslator stops returning them. - BTranslator *ptran = NULL; - for (int32 n = 0; (ptran = pMakeNthTranslator(n, image, 0)); n++) - AddTranslatorToList(ptran, path, image, false); - - return B_NO_ERROR; - - } else { - // If the translator add-on is in the R4.0 / R4.5 format - translator_data trand; - trand.translatorName = NULL; - trand.translatorInfo = NULL; - trand.translatorVersion = 0; - trand.inputFormats = NULL; - trand.outputFormats = NULL; - trand.Identify = NULL; - trand.Translate = NULL; - trand.MakeConfig = NULL; - trand.GetConfigMessage = NULL; - - char *name = NULL, *info = NULL; - translation_format *ins = NULL, *outs = NULL; - - // find all the symbols - err = get_image_symbol(image, "translatorName", B_SYMBOL_TYPE_DATA, - reinterpret_cast (&name)); - if (err) - name = NULL; - else if (!err && get_image_symbol(image, "translatorInfo", - B_SYMBOL_TYPE_DATA, reinterpret_cast (&info))) - info = NULL; - - int32 *pn = NULL; - if (!err) { - err = get_image_symbol(image, "translatorVersion", - B_SYMBOL_TYPE_DATA, reinterpret_cast (&pn)); - if (!err && (pn != NULL)) - trand.translatorVersion = *pn; - } - - if (!err && get_image_symbol(image, "inputFormats", - B_SYMBOL_TYPE_DATA, - reinterpret_cast (&ins))) - ins = NULL; - - if (!err && get_image_symbol(image, "outputFormats", - B_SYMBOL_TYPE_DATA, - reinterpret_cast (&outs))) - outs = NULL; - - if (!err) - err = get_image_symbol(image, "Identify", - B_SYMBOL_TYPE_TEXT, - reinterpret_cast (&trand.Identify)); - - if (!err) - err = get_image_symbol(image, "Translate", - B_SYMBOL_TYPE_TEXT, - reinterpret_cast (&trand.Translate)); - - if (!err && get_image_symbol(image, "MakeConfig", - B_SYMBOL_TYPE_TEXT, - reinterpret_cast (&trand.MakeConfig))) - trand.MakeConfig = NULL; - - if (!err && get_image_symbol(image, "GetConfigMessage", - B_SYMBOL_TYPE_TEXT, - reinterpret_cast (&trand.GetConfigMessage))) - trand.GetConfigMessage = NULL; - - trand.translatorName = name; - trand.translatorInfo = info; - trand.inputFormats = ins; - trand.outputFormats = outs; - - // if add-on is not in the correct format, return with error - if (err) - return err; - - // add this translator to the list - BFuncTranslator *pFuncTran = new BFuncTranslator(&trand); - AddTranslatorToList(pFuncTran, path, image, false); - // do not call Acquire() on ptran because I want it to be - // deleted the first time Release() is called on it. - - return B_NO_ERROR; - } -} - -// --------------------------------------------------------------- -// LoadDir -// -// Loads all of the translators in the directory path -// -// Preconditions: should only be called inside locked code -// -// Parameters: path, the directory of translators to load -// loadErr, the return code -// nLoaded, number of translators loaded -// -// Postconditions: -// -// Returns: B_FILE_NOT_FOUND, if the path is NULL or invalid -// other errors if LoadTranslator failed -// --------------------------------------------------------------- -void -BTranslatorRoster::LoadDir(const char *path, int32 &loadErr, int32 &nLoaded) -{ - if (!path) { - loadErr = B_FILE_NOT_FOUND; - return; - } - - loadErr = B_OK; - DIR *dir = opendir(path); - if (!dir) { - loadErr = B_FILE_NOT_FOUND; - return; - } - struct dirent *dent; - struct stat stbuf; - char cwd[PATH_MAX] = ""; - while (NULL != (dent = readdir(dir))) { - strcpy(cwd, path); - strcat(cwd, "/"); - strcat(cwd, dent->d_name); - status_t err = stat(cwd, &stbuf); - - if (!err && S_ISREG(stbuf.st_mode) && - strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) { - - err = LoadTranslator(cwd); - if (err == B_OK) - nLoaded++; - else - loadErr = err; - } - } - closedir(dir); -} - -// --------------------------------------------------------------- -// CheckFormats -// -// Function used to determine if hintType and hintMIME can be -// used to find the desired translation_format. -// -// Preconditions: Should only be called from inside locked code -// -// Parameters: inputFormats, the formats check against the hints -// inputFormatsCount, number of items in inputFormats -// hintType, the type this function is looking for -// hintMIME, the MIME type this function is looking -// for -// outFormat, NULL if no suitable translation_format -// from inputFormats was found, not NULL -// if a translation_format matching the -// hints was found -// -// -// Postconditions: -// -// Returns: true, if a determination could be made -// false, if indentification must be done -// --------------------------------------------------------------- -bool -BTranslatorRoster::CheckFormats(const translation_format *inputFormats, - int32 inputFormatsCount, uint32 hintType, const char *hintMIME, - const translation_format **outFormat) -{ - if (!inputFormats || inputFormatsCount <= 0 || !outFormat) - return false; - - *outFormat = NULL; - - // return false if we can't use hints for this module - if (!hintType && !hintMIME) - return false; - - // check for the length of the MIME string, since it may be just a prefix - // so we use strncmp(). - int mlen = 0; - if (hintMIME) - mlen = strlen(hintMIME); - - // scan for suitable format - const translation_format *fmt = inputFormats; - for (int32 i = 0; i < inputFormatsCount && fmt->type; i++, fmt++) { - if ((fmt->type == hintType) || - (hintMIME && mlen && !strncmp(fmt->MIME, hintMIME, mlen))) { - *outFormat = fmt; - return true; - } - } - // the module did export formats, but none matched. - // we return true (uses formats) but set outFormat to NULL - return true; -} - -// --------------------------------------------------------------- -// AddTranslatorToList -// -// Adds a BTranslator based object to the list of translators -// stored by the BTranslatorRoster. -// -// Preconditions: Should only be called inside locked code -// -// Parameters: translator, the translator to add to this object -// -// Postconditions: -// -// Returns: B_BAD_VALUE, if translator is NULL -// B_OK, if not -// --------------------------------------------------------------- -status_t -BTranslatorRoster::AddTranslatorToList(BTranslator *translator) -{ - return AddTranslatorToList(translator, "", -1, true); - // add translator to list with no add-on image to unload, - // and call Acquire() on it -} - -// --------------------------------------------------------------- -// AddTranslatorToList -// -// Adds a BTranslator based object to the list of translators -// stored by the BTranslatorRoster. -// -// Preconditions: Should only be called inside locked code -// -// Parameters: translator, the translator to add to this object -// path, the path the translator was loaded from -// image, the image the translator was loaded from -// acquire, if true Acquire() is called on the -// translator -// -// Postconditions: -// -// Returns: B_BAD_VALUE, if translator is NULL -// B_OK, if not -// --------------------------------------------------------------- -status_t -BTranslatorRoster::AddTranslatorToList(BTranslator *translator, - const char *path, image_id image, bool acquire) -{ - if (!translator || !path) - return B_BAD_VALUE; - - translator_node *pTranNode = new translator_node; - - if (acquire) - pTranNode->translator = translator->Acquire(); - else - pTranNode->translator = translator; - - if (fpTranslators) - pTranNode->id = fpLastTranslator->id + 1; - else - pTranNode->id = 1; - - pTranNode->path = new char[strlen(path) + 1]; - strcpy(pTranNode->path, path); - pTranNode->image = image; - pTranNode->next = NULL; - if (!fpTranslators) - fpTranslators = fpLastTranslator = pTranNode; - else { - fpLastTranslator->next = pTranNode; - fpLastTranslator = pTranNode; - } - - return B_OK; -} - -// --------------------------------------------------------------- -// ReservedTranslatorRoster1 -// -// It does nothing! :) Its here only for past/future binary -// compatibility. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -BTranslatorRoster::ReservedTranslatorRoster1() -{ -} - -// --------------------------------------------------------------- -// ReservedTranslatorRoster2 -// -// It does nothing! :) Its here only for past/future binary -// compatibility. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -BTranslatorRoster::ReservedTranslatorRoster2() -{ -} - -// --------------------------------------------------------------- -// ReservedTranslatorRoster3 -// -// It does nothing! :) Its here only for past/future binary -// compatibility. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -BTranslatorRoster::ReservedTranslatorRoster3() -{ -} - -// --------------------------------------------------------------- -// ReservedTranslatorRoster4 -// -// It does nothing! :) Its here only for past/future binary -// compatibility. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -BTranslatorRoster::ReservedTranslatorRoster4() -{ -} - -// --------------------------------------------------------------- -// ReservedTranslatorRoster5 -// -// It does nothing! :) Its here only for past/future binary -// compatibility. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -BTranslatorRoster::ReservedTranslatorRoster5() -{ -} - -// --------------------------------------------------------------- -// ReservedTranslatorRoster6 -// -// It does nothing! :) Its here only for past/future binary -// compatibility. -// -// Preconditions: -// -// Parameters: -// -// Postconditions: -// -// Returns: -// --------------------------------------------------------------- -void -BTranslatorRoster::ReservedTranslatorRoster6() -{ -} +void BTranslatorRoster::ReservedTranslatorRoster1() {} +void BTranslatorRoster::ReservedTranslatorRoster2() {} +void BTranslatorRoster::ReservedTranslatorRoster3() {} +void BTranslatorRoster::ReservedTranslatorRoster4() {} +void BTranslatorRoster::ReservedTranslatorRoster5() {} +void BTranslatorRoster::ReservedTranslatorRoster6() {} diff --git a/src/kits/translation/TranslatorRosterPrivate.h b/src/kits/translation/TranslatorRosterPrivate.h new file mode 100644 index 0000000000..92ed016c2f --- /dev/null +++ b/src/kits/translation/TranslatorRosterPrivate.h @@ -0,0 +1,82 @@ +/* + * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Author: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef TRANSLATOR_ROSTER_PRIVATE_H +#define TRANSLATOR_ROSTER_PRIVATE_H + + +#include +#include +#include +#include +#include + +#include +#include + +struct translator_data; + + +struct translator_item { + BTranslator* translator; + entry_ref ref; + image_id image; +}; + +typedef std::map TranslatorMap; +typedef std::vector MessengerList; + +class BTranslatorRoster::Private : public BHandler, public BLocker { + public: + Private(); + virtual ~Private(); + + virtual void MessageReceived(BMessage* message); + + void AddDefaultPaths(); + status_t AddPaths(const char* paths); + status_t AddPath(const char* path, int32* _added = NULL); + status_t AddTranslator(BTranslator* translator, image_id image = -1, + const entry_ref* ref = NULL); + + BTranslator* FindTranslator(translator_id id); + + status_t StoreTranslators(BMessage& archive); + status_t Identify(BPositionIO* source, BMessage* ioExtension, + uint32 hintType, const char* hintMIME, uint32 wantType, + translator_info* _info); + + status_t GetTranslators(BPositionIO* source, BMessage* ioExtension, + uint32 hintType, const char* hintMIME, uint32 wantType, + translator_info** _info, int32* _numInfo); + status_t GetAllTranslators(translator_id** _ids, int32* _count); + status_t GetRefFor(translator_id id, entry_ref& ref); + + bool IsActive() const { return Looper(); } + + status_t CreateTranslators(const entry_ref& ref, int32& count); + status_t GetTranslatorData(image_id image, translator_data& data); + + status_t StartWatching(BMessenger target); + status_t StopWatching(BMessenger target); + + void TranslatorDeleted(translator_id id); + + private: + static int _CompareSupport(const void* _a, const void* _b); + + const translation_format* _CheckHints(const translation_format* formats, + int32 formatsCount, uint32 hintType, const char* hintMIME); + const translator_item* _FindTranslator(translator_id id) const; + const translator_item* _FindTranslator(const char* name) const; + + TranslatorMap fTranslators; + MessengerList fMessengers; + int32 fNextID; +}; + +#endif // TRANSLATOR_ROSTER_PRIVATE_H