00001 #include "TupleVariableDescriptionBuilder.h"
00002 #include "AIDA_Dev/ITupleVariableDescription.h"
00003 #include "AIDA_Dev/IDevTupleFactory.h"
00004 #include "AIDA_Dev/ITupleHeader.h"
00005 #include <list>
00006
00007 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder::TupleVariableDescriptionBuilder( AIDA::Dev::IDevTupleFactory& factory ):
00008 m_factory( factory )
00009 {}
00010
00011
00012 bool
00013 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder::buildDescription( AIDA::Dev::ITupleHeader& header,
00014 const std::string& descriptionString )
00015 {
00016 std::vector<std::string> names;
00017 std::vector<std::string> types;
00018 if ( ! decompose( descriptionString, names, types ) ) return false;
00019 else return buildDescription( header, names, types );
00020 }
00021
00022
00023 bool
00024 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder::buildDescription( AIDA::Dev::ITupleHeader& header,
00025 const std::vector<std::string>& variableNames,
00026 const std::vector<std::string>& variableTypes )
00027 {
00028 return buildDescriptionT( header, variableNames, variableTypes );
00029 }
00030
00031
00032 bool
00033 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder::buildDescription( AIDA::Dev::ITupleVariableDescription& description,
00034 const std::string& descriptionString )
00035 {
00036 std::vector<std::string> names;
00037 std::vector<std::string> types;
00038 if ( ! decompose( descriptionString, names, types ) ) return false;
00039 else return buildDescription( description, names, types );
00040 }
00041
00042
00043 bool
00044 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder::buildDescription( AIDA::Dev::ITupleVariableDescription& description,
00045 const std::vector<std::string>& variableNames,
00046 const std::vector<std::string>& variableTypes )
00047 {
00048 return buildDescriptionT( description, variableNames, variableTypes );
00049 }
00050
00051
00052 static std::string cleanup( const std::string& input )
00053 {
00054 std::string description = input;
00055 bool updated = true;
00056 while ( updated ) {
00057 bool updatedLocal = false;
00058
00059 while ( description.size() > 0 ) {
00060 char last = description[ description.size() - 1 ];
00061 if ( last == ' ' || last == ';' || last == '\n' || last == '\r' || last == '\t' ) {
00062 description = description.substr( 0, description.size() - 1 );
00063 updatedLocal = true;
00064 }
00065 else {
00066 break;
00067 }
00068 }
00069
00070
00071 while ( description.size() > 0 ) {
00072 char first = description[0];
00073 if ( first == ' ' || first == ';' || first == '\n' || first == '\r' || first == '\t' ) {
00074 description = description.substr( 1 );
00075 updatedLocal = true;
00076 }
00077 else {
00078 break;
00079 }
00080 }
00081
00082
00083 while ( description.size() > 1 ) {
00084 char first = description[0];
00085 char last = description[ description.size() - 1 ];
00086 if ( first == '{' && last == '}' ) {
00087 description = description.substr( 1, description.size() - 2 );
00088 updatedLocal = true;
00089 }
00090 else {
00091 break;
00092 }
00093 }
00094 updated = updatedLocal;
00095 }
00096
00097 return description;
00098 }
00099
00100
00101 static bool tokenize( const std::string& description, std::list< std::string >& pieces, char separator )
00102 {
00103 int numberOfBraces = 0;
00104 unsigned int firstChar = 0;
00105 unsigned int lastChar = 0;
00106 for ( unsigned int i = 0; i < description.size(); ++i ) {
00107 char c = description[i];
00108 if ( c == separator ) {
00109 if ( numberOfBraces == 0 ) {
00110 if ( firstChar == i ) {
00111 ++firstChar;
00112 }
00113 else {
00114 pieces.push_back( description.substr( firstChar, i-firstChar ) );
00115 firstChar = i+1;
00116 lastChar = i;
00117 }
00118 }
00119 }
00120 else if ( c == '{' ) {
00121 ++numberOfBraces;
00122 }
00123 else if ( c == '}' ) {
00124 --numberOfBraces;
00125 if ( numberOfBraces < 0 ) return false;
00126 };
00127 }
00128
00129 if ( lastChar != description.size() ) pieces.push_back( description.substr( firstChar ) );
00130
00131 if ( numberOfBraces != 0 ) return false;
00132 else return true;
00133 }
00134
00135
00136 bool
00137 Anaphe::AIDA_Tuple_native::TupleVariableDescriptionBuilder::decompose( const std::string& input,
00138 std::vector<std::string>& variableNames,
00139 std::vector<std::string>& variableTypes ) const
00140 {
00141
00142 std::list< std::string > pieces;
00143 if ( ! tokenize( cleanup( input ), pieces, ';' ) ) return false;
00144
00145
00146 for ( std::list< std::string >::const_iterator iPiece = pieces.begin();
00147 iPiece != pieces.end(); ++iPiece ) {
00148 std::string description = cleanup( *iPiece );
00149
00150
00151 std::string varType = "";
00152 for ( unsigned int i = 0; i < description.size(); ++i ) {
00153 char c = description[i];
00154 if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '{' ) {
00155 varType = description.substr( 0, i );
00156 break;
00157 }
00158 }
00159
00160
00161 if ( varType.find( "uple" ) != std::string::npos ) {
00162 int braces = 0;
00163 for ( unsigned int i = varType.size(); i < description.size(); ++i ) {
00164 char c = description[i];
00165 varType += c;
00166 if ( c == '{' ) ++braces;
00167 else if ( c == '}' ) {
00168 --braces;
00169 if ( braces == 0 ) break;
00170 }
00171 }
00172 }
00173
00174 if ( varType != "" ) {
00175 std::list< std::string> varNames;
00176 if ( tokenize( cleanup( description.substr( varType.size() ) ), varNames, ',' ) ) {
00177 for ( std::list< std::string>::const_iterator iVarName = varNames.begin();
00178 iVarName != varNames.end(); ++iVarName ) {
00179 variableNames.push_back( cleanup( *iVarName ) );
00180 variableTypes.push_back( varType );
00181 }
00182 }
00183 }
00184 }
00185
00186 return true;
00187 }