1d25dd4b9SJérôme Duval/*
2d25dd4b9SJérôme Duval * Copyright 2009, Adrien Destugues, pulkomandy@gmail.com.
3d25dd4b9SJérôme Duval * Distributed under the terms of the MIT License.
4d25dd4b9SJérôme Duval */
575f15221SOliver Tappe/*
675f15221SOliver Tappe * This file declares all the things we need to add to a catalog add-on to be
775f15221SOliver Tappe * able to use it in the developper tools (linkcatkeys, dumpcatalog, and the
875f15221SOliver Tappe * catalog editor, when we will have one.
975f15221SOliver Tappe */
1075f15221SOliver Tappe
1175f15221SOliver Tappe
1275f15221SOliver Tappe#ifndef _HASH_MAP_CATALOG_H_
1375f15221SOliver Tappe#define _HASH_MAP_CATALOG_H_
1475f15221SOliver Tappe
1575f15221SOliver Tappe
1675f15221SOliver Tappe#include <assert.h>
1775f15221SOliver Tappe
18541ff51aSOliver Tappe#include <CatalogData.h>
1975f15221SOliver Tappe#include <HashMap.h>
2075f15221SOliver Tappe#include <String.h>
2175f15221SOliver Tappe
2275f15221SOliver Tappe
2375f15221SOliver Tappenamespace BPrivate {
2475f15221SOliver Tappe
2575f15221SOliver Tappe/*
2675f15221SOliver Tappe * The key-type for the hash_map which maps native strings or IDs to
2775f15221SOliver Tappe * the corresponding translated string.
2875f15221SOliver Tappe * The key-type should be efficient to use if it is just created by an ID
2975f15221SOliver Tappe * but it should also support being created from up to three strings,
3075f15221SOliver Tappe * which as a whole specify the key to the translated string.
3175f15221SOliver Tappe */
3275f15221SOliver Tappeclass CatKey {
3375f15221SOliver Tappe	public:
3475f15221SOliver Tappe		BString fString;
3575f15221SOliver Tappe			// The native string
3675f15221SOliver Tappe		BString fContext;
3775f15221SOliver Tappe			// The context of the string's usage
3875f15221SOliver Tappe		BString fComment;
3975f15221SOliver Tappe			// A comment that can be used to separate strings that
4075f15221SOliver Tappe			// are identical otherwise in the native language, but different in
4175f15221SOliver Tappe			// the translation (useful for the translator)
4275f15221SOliver Tappe		uint32 fHashVal;
4375f15221SOliver Tappe			// the hash-value of the key, computed from the three strings
4475f15221SOliver Tappe		uint32 fFlags;
4575f15221SOliver Tappe			// with respect to the catalog-editor, each translation can be
4675f15221SOliver Tappe			// in different states (empty, unchecked, checked, etc.). This
4775f15221SOliver Tappe			// state (and potential other flags) lives in the fFlags member.
4875f15221SOliver Tappe
4975f15221SOliver Tappe	public:
5075f15221SOliver Tappe		CatKey(const char *str, const char *ctx, const char *cmt);
5175f15221SOliver Tappe		CatKey(uint32 id);
5275f15221SOliver Tappe		CatKey();
5375f15221SOliver Tappe
5475f15221SOliver Tappe		bool operator== (const CatKey& right) const;
5575f15221SOliver Tappe		bool operator!= (const CatKey& right) const;
5675f15221SOliver Tappe		status_t GetStringParts(BString* str, BString* ctx, BString* cmt) const;
570a255c0cSAdrien Destugues		static uint32 HashFun(const char* s, int startvalue = 0);
5875f15221SOliver Tappe			// The hash function is called 3 times, cumulating the 3 strings to
5975f15221SOliver Tappe			// calculate the key
6075f15221SOliver Tappe		uint32 GetHashCode() const { return fHashVal; }
6175f15221SOliver Tappe};
6275f15221SOliver Tappe
6375f15221SOliver Tappe
64541ff51aSOliver Tappeclass HashMapCatalog: public BCatalogData {
6575f15221SOliver Tappe	protected:
6675f15221SOliver Tappe		uint32 ComputeFingerprint() const;
670a255c0cSAdrien Destugues		typedef HashMap<CatKey, BString> CatMap;
6875f15221SOliver Tappe		CatMap 				fCatMap;
6975f15221SOliver Tappe
7075f15221SOliver Tappe	public:
715ac65b7fSOliver Tappe		HashMapCatalog(const char* signature, const char* language,
7275f15221SOliver Tappe			uint32 fingerprint);
7375f15221SOliver Tappe			// Constructor for normal use
7475f15221SOliver Tappe			//
75541ff51aSOliver Tappe		// overrides of BCatalogData:
7675f15221SOliver Tappe		const char *GetString(const char *string, const char *context = NULL,
7775f15221SOliver Tappe						const char *comment = NULL);
7875f15221SOliver Tappe		const char *GetString(uint32 id);
7975f15221SOliver Tappe		const char *GetString(const CatKey& key);
8075f15221SOliver Tappe		//
8175f15221SOliver Tappe		status_t SetString(const char *string, const char *translated,
8275f15221SOliver Tappe					const char *context = NULL, const char *comment = NULL);
8375f15221SOliver Tappe		status_t SetString(int32 id, const char *translated);
8475f15221SOliver Tappe		status_t SetString(const CatKey& key, const char *translated);
8575f15221SOliver Tappe
8675f15221SOliver Tappe		// implementation for editor-interface
8775f15221SOliver Tappe		virtual status_t ReadFromFile(const char *path = NULL)
8875f15221SOliver Tappe			{return B_NOT_SUPPORTED;}
891a5c1f9eSAdrien Destugues		virtual status_t ReadFromAttribute(const entry_ref &appOrAddOnRef)
9075f15221SOliver Tappe			{return B_NOT_SUPPORTED;}
911a5c1f9eSAdrien Destugues		virtual status_t ReadFromResource(const entry_ref &appOrAddOnRef)
9275f15221SOliver Tappe			{return B_NOT_SUPPORTED;}
9375f15221SOliver Tappe		virtual status_t WriteToFile(const char *path = NULL)
9475f15221SOliver Tappe			{return B_NOT_SUPPORTED;}
951a5c1f9eSAdrien Destugues		virtual status_t WriteToAttribute(const entry_ref &appOrAddOnRef)
9675f15221SOliver Tappe			{return B_NOT_SUPPORTED;}
971a5c1f9eSAdrien Destugues		virtual status_t WriteToResource(const entry_ref &appOrAddOnRef)
9875f15221SOliver Tappe			{return B_NOT_SUPPORTED;}
9975f15221SOliver Tappe
10075f15221SOliver Tappe		void UpdateFingerprint();
10175f15221SOliver Tappe		//
10275f15221SOliver Tappe		void MakeEmpty();
10375f15221SOliver Tappe		int32 CountItems() const;
10475f15221SOliver Tappe
10575f15221SOliver Tappe		/*
10675f15221SOliver Tappe		 * CatWalker allows to walk trough all the strings stored in the
10775f15221SOliver Tappe		 * catalog. We need that for dumpcatalog, linkcatkeys (to extract the
10875f15221SOliver Tappe		 * data from the plaintext catalog) and in the catalog editor (to
10975f15221SOliver Tappe		 * display the list of strings in a given catalog).
11075f15221SOliver Tappe		 */
11175f15221SOliver Tappe		class CatWalker {
11275f15221SOliver Tappe			public:
11375f15221SOliver Tappe				//CatWalker() {}; // if you use this there is no way to set fPos
11475f15221SOliver Tappe				// properly.
1155ac65b7fSOliver Tappe				CatWalker(HashMapCatalog* catalog);
11675f15221SOliver Tappe				bool AtEnd() const;
11775f15221SOliver Tappe				const CatKey& GetKey() const;
11875f15221SOliver Tappe				const char *GetValue() const;
11975f15221SOliver Tappe				void Next();
12075f15221SOliver Tappe			private:
12175f15221SOliver Tappe				CatMap::Iterator fPos;
12275f15221SOliver Tappe				CatMap::Entry current;
12375f15221SOliver Tappe				bool atEnd;
12475f15221SOliver Tappe		};
12575f15221SOliver Tappe		friend class CatWalker;
12675f15221SOliver Tappe		status_t GetWalker(CatWalker *walker);
12775f15221SOliver Tappe
12875f15221SOliver Tappe
12975f15221SOliver Tappe};
13075f15221SOliver Tappe
13175f15221SOliver Tappe
1325ac65b7fSOliver Tappeinline HashMapCatalog::HashMapCatalog(const char* signature,
13375f15221SOliver Tappe	const char* language, uint32 fingerprint)
13475f15221SOliver Tappe	:
135541ff51aSOliver Tappe	BCatalogData(signature, language, fingerprint)
13675f15221SOliver Tappe{
13775f15221SOliver Tappe}
13875f15221SOliver Tappe
13975f15221SOliver Tappe
14075f15221SOliver Tappeinline
1415ac65b7fSOliver TappeHashMapCatalog::CatWalker::CatWalker(HashMapCatalog* catalog)
14275f15221SOliver Tappe	:
14375f15221SOliver Tappe	fPos(catalog->fCatMap.GetIterator())
14475f15221SOliver Tappe{
14575f15221SOliver Tappe	if (fPos.HasNext()) {
14675f15221SOliver Tappe		current = fPos.Next();
14775f15221SOliver Tappe		atEnd = false;
14875f15221SOliver Tappe	} else
14975f15221SOliver Tappe		atEnd = true;
15075f15221SOliver Tappe}
15175f15221SOliver Tappe
15275f15221SOliver Tappe
15375f15221SOliver Tappeinline bool
1545ac65b7fSOliver TappeHashMapCatalog::CatWalker::AtEnd() const
15575f15221SOliver Tappe{
15675f15221SOliver Tappe	return atEnd;
15775f15221SOliver Tappe}
15875f15221SOliver Tappe
15975f15221SOliver Tappe
16075f15221SOliver Tappeinline const CatKey &
1615ac65b7fSOliver TappeHashMapCatalog::CatWalker::GetKey() const
16275f15221SOliver Tappe{
16375f15221SOliver Tappe	assert(!atEnd);
16475f15221SOliver Tappe	return current.key;
16575f15221SOliver Tappe}
16675f15221SOliver Tappe
16775f15221SOliver Tappe
16875f15221SOliver Tappeinline const char *
1695ac65b7fSOliver TappeHashMapCatalog::CatWalker::GetValue() const
17075f15221SOliver Tappe{
17175f15221SOliver Tappe	assert(!atEnd);
17275f15221SOliver Tappe	return current.value.String();
17375f15221SOliver Tappe}
17475f15221SOliver Tappe
17575f15221SOliver Tappe
17675f15221SOliver Tappeinline void
1775ac65b7fSOliver TappeHashMapCatalog::CatWalker::Next()
17875f15221SOliver Tappe{
17975f15221SOliver Tappe	if (fPos.HasNext()) {
18075f15221SOliver Tappe		current = fPos.Next();
18175f15221SOliver Tappe		atEnd = false;
18275f15221SOliver Tappe	} else
18375f15221SOliver Tappe		atEnd = true;
18475f15221SOliver Tappe}
18575f15221SOliver Tappe
18675f15221SOliver Tappe
18775f15221SOliver Tappeinline status_t
1885ac65b7fSOliver TappeHashMapCatalog::GetWalker(CatWalker *walker)
18975f15221SOliver Tappe{
19075f15221SOliver Tappe	if (!walker)
19175f15221SOliver Tappe		return B_BAD_VALUE;
19275f15221SOliver Tappe	*walker = CatWalker(this);
19375f15221SOliver Tappe	return B_OK;
19475f15221SOliver Tappe}
19575f15221SOliver Tappe
19675f15221SOliver Tappe
19775f15221SOliver Tappe} // namespace BPrivate
19875f15221SOliver Tappe
19975f15221SOliver Tappe#endif // _HASH_MAP_CATALOG_H_