Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
MP21.cpp
00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: MP21.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 #include "MP21.hpp" 00045 #include "TerminalCapabilities.hpp" 00046 #include "UserPreferences.hpp" 00047 #include <string.h> 00048 #include "debug.hpp" 00049 00050 const char* const MP21::openHeader="<xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<DIDL xmlns=\"urn:mpeg:mpeg21:dia:schema:2003\">"; 00051 const char* const MP21::closeHeader="</DIDL>"; 00052 const char* const MP21::boolStrings[2]={"FALSE","TRUE"}; 00053 const char* MP21::getMP21DocumentOpeningHeader() { 00054 return openHeader; 00055 }; 00056 00057 const char* MP21::getMP21DocumentClosingHeader() { 00058 return closeHeader; 00059 }; 00060 00061 char* MP21::generateTerminalCapabilityDescription(const TerminalCapabilities* tc) { 00062 /*create a minimum MPEG21 description 00063 <TerminalCapabilities> 00064 <InputOutput> 00065 <Display bitsPerPixel="8" colorCapable="TRUE" refreshRate="60"> 00066 <Resolution horizontal="352" vertical="288"/> 00067 </Display> 00068 </InputOutput> 00069 <AudioOut samplingFrequency="44100" bitsPerSample="16" numChannels="1"/> 00070 <DeviceProperty> 00071 <Storage> 00072 <Device Size="4.5"/> <!-- in MByte --> 00073 </Storage> 00074 <Network> 00075 <NetworkCapability maxCapacity="64000" minGuaranteed="32000"/> 00076 <Delay delayVariation="25"/> 00077 </Network> 00078 </DeviceProperty> 00079 </TerminalCapabilities> */ 00080 char *buffer = new char[32768]; 00081 char* pBuffer=buffer; 00082 strcpy(buffer, openHeader); 00083 pBuffer+=strlen(openHeader); 00084 sprintf(pBuffer,"\t<TerminalCapabilities>\r\n\t\t<InputOutput>\r\n\t\t\t"); 00085 pBuffer+=strlen(pBuffer); 00086 // write IO part 00087 sprintf(pBuffer,"<Display bitsPerPixel=\"%u\" colorCapable=\"%s\" refreshRate=\"%u\">\r\n" 00088 "\t\t\t\t<Resolution horizontal=\"%u\" vertical=\"%u\"/>\r\n" 00089 "\t\t\t</Display>\r\n\t\t</InputOutput>\r\n", 00090 tc->getDisplayBitsPerPixel(), 00091 boolStrings[tc->getColorDisplay()], 00092 tc->getDisplayRefreshRate(), 00093 tc->getDisplayWidth(),tc->getDisplayHeight()); 00094 pBuffer+=strlen(pBuffer); 00095 // generate Audio 00096 if(tc->supportsAudio()) { 00097 sprintf(pBuffer,"\t\t<AudioOut samplingFrequency \"%u\" bitsPerSample \"%u\" numChannels=\"%u\"/>\r\n", 00098 tc->getAudioSamplingFrequency(),tc->getAudioBitsPerSample(),tc->getNumAudioChannels()); 00099 pBuffer+=strlen(pBuffer); 00100 } 00101 // write DeviceProperty 00102 sprintf(pBuffer,"\t\t<DeviceProperty>\r\n" 00103 "\t\t\t<Storage>\r\n" 00104 "\t\t\t\t<Device Size=\"%f\"/>\r\n" 00105 "\t\t\t</Storage>\r\n" 00106 "\t\t\t<Network>\r\n" 00107 "\t\t\t\t<NetworkCapability maxCapability=\"%i\" minGuaranteed=\"%i\"/>\r\n" 00108 "\t\t\t\t<Delay delayVariation=\"%i\"/>\r\n" 00109 "\t\t\t</Network>\r\n" 00110 "\t\t</DeviceProperty>\r\n" 00111 "\t</TerminalCapabilities>\r\n" 00112 , 00113 tc->getMemoryStorageMB(), 00114 tc->getNetworkCapacityInByte(),tc->getMinGuaranteedNetworkCapacityInByte(), 00115 tc->getNetworkDelayVariationInMs()); 00116 pBuffer+=strlen(pBuffer); 00117 strcat(pBuffer,closeHeader); 00118 char* result=new char[strlen(buffer)+1]; 00119 strcpy(result,buffer); 00120 00121 delete [] buffer; 00122 return result; 00123 }; 00124 00125 TerminalCapabilities* MP21::createTerminalCapability(const char* mp21string) { 00126 // look for openheader 00127 if(strstr(mp21string,MP21::openHeader)==NULL) 00128 return NULL; 00129 00130 TerminalCapabilities* tc=new TerminalCapabilities(); 00131 // lazy parsing 00132 char* pBuffer=strstr(mp21string, "<Display"); 00133 char* pBufferEnd=NULL; 00134 if(pBuffer) { 00135 pBufferEnd=strstr(pBuffer, "</Display>"); 00136 } 00137 char *sTemp = new char[2000]; 00138 int temp; 00139 if(pBuffer && pBufferEnd) { 00140 if(findIntAfterToken(pBuffer,pBufferEnd,"bitsPerPixel",&temp)) 00141 tc->setDisplayBitsPerPixel((u8)temp); 00142 if(findStringAfterToken(pBuffer,pBufferEnd,"colorCapable",sTemp)) { 00143 if((strcmp(sTemp,"TRUE")==0) || (strcmp(sTemp,"true")==0) ) { 00144 tc->setColorDisplay(true); 00145 dprintf_full("MP21::createTerminalCapability: found true: X%sX\r\n",sTemp); 00146 } 00147 else { 00148 dprintf_full("MP21::createTerminalCapability: found true: X%sX\r\n",sTemp); 00149 tc->setColorDisplay(false); 00150 } 00151 } 00152 if(findIntAfterToken(pBuffer,pBufferEnd,"refreshRate",&temp)) 00153 tc->setDisplayRefreshRate(temp); 00154 if(findIntAfterToken(pBuffer,pBufferEnd,"horizontal",&temp)) 00155 tc->setDisplayWidth(temp); 00156 if(findIntAfterToken(pBuffer,pBufferEnd,"vertical",&temp)) 00157 tc->setDisplayHeight(temp); 00158 } 00159 // search Audio part 00160 // <AudioOut samplingFrequency="44100" bitsPerSample="16" numChannels="1"/> 00161 pBuffer=NULL;pBufferEnd=NULL; 00162 pBuffer=strstr(mp21string,"<AudioOut"); 00163 if(pBuffer) 00164 pBufferEnd=strstr(pBuffer,"/>"); 00165 if(pBuffer && pBufferEnd) { 00166 if(findIntAfterToken(pBuffer,pBufferEnd,"samplingFrequency",&temp)) 00167 tc->setAudioSamplingFrequency(temp); 00168 if(findIntAfterToken(pBuffer,pBufferEnd,"bitsPerSample",&temp)) 00169 tc->setAudioBitsPerSample((u8)temp); 00170 if(findIntAfterToken(pBuffer,pBufferEnd,"numChannels",&temp)) 00171 tc->setNumAudioChannels((u8)temp); 00172 } 00173 00174 pBuffer=NULL;pBufferEnd=NULL; 00175 pBuffer=strstr(mp21string,"<DeviceProperty>"); 00176 if(pBuffer) 00177 pBufferEnd=strstr(mp21string,"</DeviceProperty>"); 00178 00179 if(pBuffer && pBufferEnd) { 00180 char* pStorage=strstr(pBuffer,"<Storage>"); 00181 char* pStorageEnd=strstr(pBuffer,"</Storage>"); 00182 if(pStorage && pStorageEnd) { 00183 float result; 00184 if(findFloatAfterToken(pStorage,pStorageEnd,"Size",&result)) 00185 tc->setMemoryStorageMB(result); 00186 } 00187 pStorage=strstr(pBuffer,"<Network>"); 00188 pStorageEnd=strstr(pBuffer,"</Network>"); 00189 if(pStorage && pStorageEnd) { 00190 if(findIntAfterToken(pStorage,pStorageEnd,"maxCapability",&temp)) 00191 tc->setNetworkCapacityInByte(temp); 00192 if(findIntAfterToken(pStorage,pStorageEnd,"minGuaranteed",&temp)) 00193 tc->setMinGuaranteedNetworkCapacityInByte(temp); 00194 if(findIntAfterToken(pStorage,pStorageEnd,"delayVariation",&temp)) 00195 tc->setNetworkDelayVariationInMs(temp); 00196 } 00197 } 00198 delete [] sTemp; 00199 return tc; 00200 }; 00201 00202 bool MP21::findIntAfterToken(const char* input, const char* inputEnd, 00203 const char* token, int* result) { 00204 char* temp=strstr(input,token); 00205 if(!temp ) 00206 return false; 00207 if(temp>inputEnd) 00208 return false; 00209 temp+=strlen(token); // point after token 00210 // found the token 00211 // after the token the only valid chars are '=', ' ' and stop condition is '"' 00212 while( (*temp)=='=' || 00213 (*temp)==' ') { 00214 temp++; 00215 } 00216 if(*temp=='"') { 00217 temp++; 00218 if(temp>inputEnd) 00219 return false; 00220 return (sscanf(temp,"%i",result)==1); 00221 } 00222 return false; 00223 }; 00224 00225 bool MP21::findFloatAfterToken(const char* input, const char* inputEnd, 00226 const char* token, float* result) { 00227 char* temp=strstr(input,token); 00228 if(!temp ) 00229 return false; 00230 if(temp>inputEnd) 00231 return false; 00232 temp+=strlen(token); // point after token 00233 // found the token 00234 // after the token the only valid chars are '=', ' ' and stop condition is '"' 00235 while( (*temp)=='=' || 00236 (*temp)==' ') { 00237 temp++; 00238 } 00239 if(*temp=='"') { 00240 temp++; 00241 if(temp>inputEnd) 00242 return false; 00243 return (sscanf(temp,"%f",result)==1); 00244 } 00245 return false; 00246 }; 00247 00248 00249 bool MP21::findStringAfterToken(const char* input, const char* inputEnd, 00250 const char* token, char* result) { 00251 char* temp=strstr(input,token); 00252 if(!temp) 00253 return false; 00254 if(temp>inputEnd) 00255 return false; 00256 00257 temp+=strlen(token); // point after token 00258 // found the token 00259 // after the token the only valid chars are = , ' ' and stop condition is '"' 00260 while( (*temp)=='=' || 00261 (*temp)==' ') { 00262 temp++; 00263 } 00264 if(*temp=='"') { 00265 temp++; 00266 // find the closing '"' in the same line 00267 char* pEnd=temp; 00268 while(*pEnd!='"' && *pEnd!='\r' && *pEnd!='\n') 00269 pEnd++; 00270 if(*pEnd=='"' && pEnd<=inputEnd) { 00271 // valid 00272 strncpy(result,temp,pEnd-temp); 00273 result[pEnd-temp]='\0'; 00274 return true; 00275 } 00276 } 00277 return false; 00278 }; 00279 00283 char* MP21::generateUserPreferencesDescription(const UserPreferences* up) 00284 { 00285 return up->toString(); 00286 } 00287 00289 UserPreferences* MP21::createUserPreferences(const char* mp21string) 00290 { 00291 00292 return UserPreferences::create(mp21string); 00293 } 00294