1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "xml_cdim.hxx"
25 
26 const char ComponentDescriptionImpl::C_sTagDescription[]
27 										=   "COMPONENTDESCRIPTION";
28 const char ComponentDescriptionImpl::C_sStatus[]
29 										=   "Status";
30 const char * ComponentDescriptionImpl::C_sSubTags[ComponentDescription::tag_MAX]
31 										= {	"None",
32 										    "Name",
33 											"Description",
34 											"ModuleName",
35 											"LoaderName",
36 											"SupportedService",
37 											"ProjectBuildDependency",
38 											"RuntimeModuleDependency",
39 											"ServiceDependency",
40 											"Language",
41 											C_sStatus,
42 											"Type"
43 										  };
44 
ComponentDescriptionImpl()45 ComponentDescriptionImpl::ComponentDescriptionImpl()
46 //	:	aTags
47 {
48 	const int i_max = tag_MAX;
49 	aTags.reserve(i_max);
50 
51 	for (int i = 0; i < i_max; ++i)
52 	{
53 		aTags.push_back( new ValueList(E_Tag(i)) );
54 	}  // end for
55 }
56 
~ComponentDescriptionImpl()57 ComponentDescriptionImpl::~ComponentDescriptionImpl()
58 {
59 	for ( std::vector< ValueList* >::iterator aIter = aTags.begin();
60 		  aIter != aTags.end();
61 		  ++aIter )
62 	{
63 		delete *aIter;
64 	}
65 }
66 
67 inline void
GetStatusValue(ByteString & o_sValue,const ByteString & i_sStatusTag)68 GetStatusValue( ByteString & o_sValue, const ByteString & i_sStatusTag )
69 {
70 	// o_sValue is always == "" at the beginning.
71 
72 	const char * pStatusValue = strchr(i_sStatusTag.GetBuffer(), '"');
73 	if (pStatusValue == 0)
74 		return;
75 	pStatusValue++;
76 	const char * pStatusValueEnd = strrchr(pStatusValue,'"');
77 	if (pStatusValueEnd == 0 || pStatusValueEnd - pStatusValue < 1)
78 		return ;
79 
80 	ByteString sValue(pStatusValue, pStatusValueEnd - pStatusValue);
81 	o_sValue = sValue;
82 }
83 
84 ComponentDescriptionImpl::ValueList *
GetBeginTag(ByteString & o_sValue,const char * & io_pStartOfTag) const85 ComponentDescriptionImpl::GetBeginTag( ByteString &	 o_sValue,
86 									   const char *& io_pStartOfTag ) const
87 {
88 	o_sValue = "";
89 
90 	const char * pCurTextEnd = strchr(io_pStartOfTag,'>');
91 	if ( 0 == pCurTextEnd )
92 		return 0;
93 
94 	if ( ComponentDescriptionImpl::CheckEndOfDescription(io_pStartOfTag) )
95     	return 0;
96 
97 	ByteString sTag(io_pStartOfTag + 1, pCurTextEnd - io_pStartOfTag - 1);
98 	io_pStartOfTag += sTag.Len() + 2;
99 
100 	// Special case <Status ... >
101 	if ( strnicmp(C_sStatus, sTag.GetBuffer(), (sizeof C_sStatus) - 1 ) == 0 )
102 	{
103 		GetStatusValue(o_sValue,sTag);
104 		return aTags[tag_Status];
105 	}
106 
107 	// Regular seeking for matching data list:
108 	for ( INT32 i = 0; i < tag_MAX; i++ )
109 	{
110 		if ( 0 == stricmp(sTag.GetBuffer(), C_sSubTags[i]) )
111 			return aTags[i];
112 	}	// end for
113 
114 	return 0;
115 }
116 
117 const std::vector< ByteString > &
DataOf(ComponentDescriptionImpl::E_Tag i_eTag) const118 ComponentDescriptionImpl::DataOf( ComponentDescriptionImpl::E_Tag i_eTag ) const
119 {
120 	if (0 < i_eTag && i_eTag < tag_MAX)
121 		return *aTags[i_eTag];
122 	else
123 		return ValueList::Null_();
124 }
125 
126 ByteString
DatumOf(ComponentDescriptionImpl::E_Tag i_eTag) const127 ComponentDescriptionImpl::DatumOf( ComponentDescriptionImpl::E_Tag i_eTag ) const
128 {
129 	if (0 < i_eTag && i_eTag < tag_MAX)
130 	{
131 		ValueList & rValues = *aTags[i_eTag];
132 		if (rValues.size() > 0)
133 			return rValues[0];
134 	}
135 	return "";
136 }
137 
138 void
ParseUntilStartOfDescription(const char * & io_pBufferPosition)139 ComponentDescriptionImpl::ParseUntilStartOfDescription( const char * & io_pBufferPosition )
140 {
141 	for ( const char * pSearch = strchr(io_pBufferPosition,'<');
142 		  pSearch != 0;
143 		  pSearch = strchr(pSearch+1,'<') )
144 	{
145 		if ( pSearch != io_pBufferPosition
146 			 && 0 == strnicmp(pSearch+1,C_sTagDescription, strlen(C_sTagDescription))
147 			 && *(pSearch + strlen(C_sTagDescription) + 1) == '>' )
148 		{
149 			io_pBufferPosition = pSearch + strlen(C_sTagDescription) + 2;
150 			return;
151 		}
152 	}	// end for
153 
154 	io_pBufferPosition = 0;
155 }
156 
157 BOOL
MatchesEndTag(const char * i_pTextPosition) const158 ComponentDescriptionImpl::ValueList::MatchesEndTag( const char * i_pTextPosition ) const
159 {
160 	return strnicmp( i_pTextPosition+2, C_sSubTags[eTag], strlen(C_sSubTags[eTag]) ) == 0
161 		   && strncmp(i_pTextPosition,"</",2) == 0
162 		   && *(i_pTextPosition + 2 + strlen(C_sSubTags[eTag]) ) == '>';
163 }
164 
165 INT32
EndTagLength() const166 ComponentDescriptionImpl::ValueList::EndTagLength() const
167 {
168 	return strlen(C_sSubTags[eTag]) + 3;
169 }
170 
171 
172 const ComponentDescriptionImpl::ValueList &
Null_()173 ComponentDescriptionImpl::ValueList::Null_()
174 {
175 	static const ValueList aNull_(ComponentDescription::tag_None);
176     return aNull_;
177 }
178 
179 
180