summaryrefslogtreecommitdiff
path: root/cpp/src/slice2freezej/Main.cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2004-09-30 20:01:20 +0000
committerBernard Normier <bernard@zeroc.com>2004-09-30 20:01:20 +0000
commit7449ae7ee48b15f59ce1cdd5b8474aa159f9ad92 (patch)
tree5f6f029d316ab667ffdb54ad5cee4e4262fffaa6 /cpp/src/slice2freezej/Main.cpp
parentmore glacier2 (diff)
downloadice-7449ae7ee48b15f59ce1cdd5b8474aa159f9ad92.tar.bz2
ice-7449ae7ee48b15f59ce1cdd5b8474aa159f9ad92.tar.xz
ice-7449ae7ee48b15f59ce1cdd5b8474aa159f9ad92.zip
Map index support
Diffstat (limited to 'cpp/src/slice2freezej/Main.cpp')
-rw-r--r--cpp/src/slice2freezej/Main.cpp381
1 files changed, 379 insertions, 2 deletions
diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp
index 4079ba2ed0a..4f47302b2aa 100644
--- a/cpp/src/slice2freezej/Main.cpp
+++ b/cpp/src/slice2freezej/Main.cpp
@@ -14,11 +14,19 @@ using namespace std;
using namespace Slice;
using namespace IceUtil;
+struct DictIndex
+{
+ string member;
+ bool caseSensitive;
+};
+
struct Dict
{
string name;
string key;
string value;
+
+ vector<DictIndex> indices;
};
struct Index
@@ -93,6 +101,106 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict)
}
TypePtr valueType = valueTypes.front();
+ vector<TypePtr> indexTypes;
+ vector<string> capitalizedMembers;
+ vector<string> indexNames;
+ size_t i;
+
+ for(i = 0; i < dict.indices.size(); ++i)
+ {
+ const DictIndex& index = dict.indices[i];
+ const string& member = index.member;
+
+ if(index.member.empty())
+ {
+ if(dict.indices.size() > 1)
+ {
+ cerr << _prog << ": bad index for dictionary `" << dict.name << "'" << endl;
+ return false;
+ }
+
+ if(index.caseSensitive == false)
+ {
+ //
+ // Let's check value is a string
+ //
+
+ BuiltinPtr builtInType = BuiltinPtr::dynamicCast(valueType);
+
+ if(builtInType == 0 || builtInType->kind() != Builtin::KindString)
+ {
+ cerr << _prog << ": VALUE is a `" << dict.value << "', not a string " << endl;
+ return false;
+ }
+ }
+ indexTypes.push_back(valueType);
+ capitalizedMembers.push_back("Value");
+ indexNames.push_back("index");
+ }
+ else
+ {
+ DataMemberPtr dataMember = 0;
+ DataMemberList dataMembers;
+
+ ClassDeclPtr classDecl = ClassDeclPtr::dynamicCast(valueType);
+ if(classDecl != 0)
+ {
+ dataMembers = classDecl->definition()->allDataMembers();
+ }
+ else
+ {
+ StructPtr structDecl = StructPtr::dynamicCast(valueType);
+ if(structDecl == 0)
+ {
+ cerr << _prog << ": `" << dict.value << "' is neither a class nor a struct." << endl;
+ return false;
+ }
+ dataMembers = structDecl->dataMembers();
+ }
+ DataMemberList::const_iterator q = dataMembers.begin();
+ while(q != dataMembers.end() && dataMember == 0)
+ {
+ if((*q)->name() == index.member)
+ {
+ dataMember = *q;
+ }
+ else
+ {
+ ++q;
+ }
+ }
+
+ if(dataMember == 0)
+ {
+ cerr << _prog << ": The value of `" << dict.name
+ << "' has no data member named `" << index.member << "'" << endl;
+ return false;
+ }
+
+ TypePtr dataMemberType = dataMember->type();
+
+ if(index.caseSensitive == false)
+ {
+ //
+ // Let's check member is a string
+ //
+ BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMemberType);
+ if(memberType == 0 || memberType->kind() != Builtin::KindString)
+ {
+ cerr << _prog << ": `" << index.member << "'is not a string " << endl;
+ return false;
+ }
+ }
+ indexTypes.push_back(dataMemberType);
+
+ string capitalizedMember = member;
+ capitalizedMember[0] = toupper(capitalizedMember[0]);
+ capitalizedMembers.push_back(capitalizedMember);
+ indexNames.push_back(member);
+ }
+ }
+
+
if(!open(dict.name))
{
cerr << _prog << ": unable to open class " << dict.name << endl;
@@ -107,12 +215,141 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict)
//
// Constructor
//
- out << sp << nl << "public" << nl << name << "(Freeze.Connection connection, String dbName, boolean createDb)";
+ out << sp << nl << "public" << nl << name
+ << "(Freeze.Connection __connection, String __dbName, boolean __createDb)";
out << sb;
- out << nl << "super(connection, dbName, createDb);";
+ if(dict.indices.size() == 0)
+ {
+ out << nl << "super(__connection, __dbName, __createDb);";
+ }
+ else
+ {
+ out << nl << "super(__connection, __dbName);";
+ out << nl << "_indices = new Freeze.Map.Index[" << dict.indices.size() << "];";
+ for(i = 0; i < dict.indices.size(); ++i)
+ {
+ out << nl << "_indices[" << i << "] = new " << capitalizedMembers[i]
+ << "Index(\"" << indexNames[i] << "\");";
+ }
+ out << nl << "init(_indices, __dbName, __createDb);";
+ }
out << eb;
//
+ // findBy, count and encode methods
+ //
+
+ for(i = 0; i < capitalizedMembers.size(); ++i)
+ {
+ string indexClassName = capitalizedMembers[i] + "Index";
+
+ out << sp << nl << "public Freeze.Map.EntryIterator";
+ out << nl << "findBy" << capitalizedMembers[i] << "("
+ << typeToString(indexTypes[i], TypeModeIn) << " __index)";
+ out << sb;
+ out << nl << "return _indices[" << i << "].untypedFind("
+ << "encode" << indexClassName
+ << "(__index, ((Freeze.Connection)_connection).getCommunicator()));";
+ out << eb;
+
+
+ string countMethod = dict.indices[i].member.empty() ?
+ "valueCount" : dict.indices[i].member + "Count";
+ out << sp << nl << "public int";
+ out << nl << countMethod << "("
+ << typeToString(indexTypes[i], TypeModeIn) << " __index)";
+ out << sb;
+ out << nl << "return _indices[" << i << "].untypedCount("
+ << "encode" << indexClassName
+ << "(__index, ((Freeze.Connection)_connection).getCommunicator()));";
+ out << eb;
+
+
+ out << sp << nl << "private byte[]";
+ out << nl << "encode" << indexClassName << "(" << typeToString(indexTypes[i], TypeModeIn)
+ << " __key, Ice.Communicator __communicator)";
+ out << sb;
+ if(dict.indices[i].member.empty() && dict.indices[i].caseSensitive)
+ {
+ string param;
+ BuiltinPtr b = BuiltinPtr::dynamicCast(indexTypes[i]);
+ if(b != 0)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ param = "new java.lang.Byte(__key)";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ param = "new java.lang.Boolean(__key)";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ param = "new java.lang.Short(__key)";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ param = "new java.lang.Integer(__key)";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ param = "new java.lang.Long(__key)";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ param = "new java.lang.Float(__key)";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ param = "new java.lang.Double(__key)";
+ break;
+ }
+ default:
+ {
+ param = "__key";
+ break;
+ }
+ }
+ }
+
+ out << nl << "return encodeValue(" << param << ", __communicator);";
+ }
+ else
+ {
+ string valueS = dict.indices[i].caseSensitive ? "__key" : "__key.toLowerCase()";
+
+ out << nl << "IceInternal.BasicStream __os = "
+ << "new IceInternal.BasicStream(Ice.Util.getInstance(__communicator));";
+ out << nl << "try";
+ out << sb;
+ int iter = 0;
+ writeMarshalUnmarshalCode(out, "", indexTypes[i], valueS, true, iter, false);
+ if(indexTypes[i]->usesClasses())
+ {
+ out << nl << "__os.writePendingObjects();";
+ }
+ out << nl << "java.nio.ByteBuffer __buf = __os.prepareWrite();";
+ out << nl << "byte[] __r = new byte[__buf.limit()];";
+ out << nl << "__buf.get(__r);";
+ out << nl << "return __r;";
+ out << eb;
+ out << nl << "finally";
+ out << sb;
+ out << nl << "__os.destroy();";
+ out << eb;
+ }
+ out << eb;
+ }
+
+ //
// encode/decode
//
for(int i = 0; i < 2; i++)
@@ -344,6 +581,46 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict)
out << eb;
}
+
+ //
+ // Inner index classes
+ //
+ for(i = 0; i < capitalizedMembers.size(); ++i)
+ {
+ string indexClassName = capitalizedMembers[i] + "Index";
+ out << sp << nl << "private class " << indexClassName << " extends Freeze.Map.Index";
+ out << sb;
+
+ out << sp << nl << "protected byte[]";
+ out << nl << "marshalKey(byte[] __value)";
+ out << sb;
+ if(dict.indices[i].member.empty() && dict.indices[i].caseSensitive)
+ {
+ out << nl << "return __value;";
+ }
+ else
+ {
+ out << nl << typeToString(valueType, TypeModeIn)
+ << " __x = ("
+ << typeToString(valueType, TypeModeIn) <<
+ ")decodeValue(__value, ((Freeze.Connection)_connection).getCommunicator());";
+ string param = "__x";
+ if(!dict.indices[i].member.empty())
+ {
+ param += "." + dict.indices[i].member;
+ }
+ out << nl << "return encode" << indexClassName << "(" << param
+ << ", ((Freeze.Connection)_connection).getCommunicator());";
+ }
+ out << eb;
+
+ out << sp << nl << "private " << indexClassName << "(String name)";
+ out << sb;
+ out << nl << "super(name);";
+ out << eb;
+ out << eb;
+ }
+
//
// Patcher class.
//
@@ -380,8 +657,14 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict)
out << eb;
}
+ //
+ // Fields
+ //
+ out << sp << nl << "private Freeze.Map.Index[] _indices;";
+
out << eb;
+
close();
return true;
@@ -574,6 +857,14 @@ usage(const char* n)
" different names. NAME may be a scoped name.\n"
" When member is a string, the case can be\n"
" sensitive or insensitive (default is sensitive).\n"
+ "--dict-index DICT[,MEMBER][,{case-sensitive|case-insensitive}] \n"
+ " Add an index to dictionary DICT. If MEMBER is \n"
+ " specified, then DICT's VALUE must be a class or\n"
+ " a struct, and MEMBER must designate a member of\n"
+ " VALUE. Otherwise, the entire VALUE is used for \n"
+ " indexing. When the secondary key is a string, \n"
+ " the case can be sensitive or insensitive (default\n"
+ " is sensitive).\n"
"--output-dir DIR Create files in the directory DIR.\n"
"--depend Generate Makefile dependencies.\n"
"-d, --debug Print debug messages.\n"
@@ -764,6 +1055,92 @@ main(int argc, char* argv[])
}
argc -= 2;
}
+ else if(strcmp(argv[idx], "--dict-index") == 0)
+ {
+ if(idx + 1 >= argc || argv[idx + 1][0] == '-')
+ {
+ cerr << argv[0] << ": argument expected for `" << argv[idx] << "'" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ string s = argv[idx + 1];
+ s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end());
+
+ string dictName;
+ DictIndex index;
+ string::size_type pos;
+
+ string caseString = "case-sensitive";
+ pos = s.find(',');
+ if(pos != string::npos)
+ {
+ dictName = s.substr(0, pos);
+ s.erase(0, pos + 1);
+
+ pos = s.find(',');
+ if(pos != string::npos)
+ {
+ index.member = s.substr(0, pos);
+ s.erase(0, pos + 1);
+ caseString = s;
+ }
+ else
+ {
+ if(s == "case-sensitive" || s == "case-insensitive")
+ {
+ caseString = s;
+ }
+ else
+ {
+ index.member = s;
+ }
+ }
+ }
+ else
+ {
+ dictName = s;
+ }
+
+ if(dictName.empty())
+ {
+ cerr << argv[0] << ": " << argv[idx] << ": no dictionary specified" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(caseString != "case-sensitive" && caseString != "case-insensitive")
+ {
+ cerr << argv[0] << ": " << argv[idx]
+ << ": the case can be `case-sensitive' or `case-insensitive'" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+ index.caseSensitive = (caseString == "case-sensitive");
+
+ bool found = false;
+ for(vector<Dict>::iterator p = dicts.begin(); p != dicts.end(); ++p)
+ {
+ if(p->name == dictName)
+ {
+ p->indices.push_back(index);
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ cerr << argv[0] << ": " << argv[idx] << ": unknown dictionary" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ for(int i = idx ; i + 2 < argc ; ++i)
+ {
+ argv[i] = argv[i + 2];
+ }
+ argc -= 2;
+ }
else if(strcmp(argv[idx], "-h") == 0 || strcmp(argv[idx], "--help") == 0)
{
usage(argv[0]);