XRootD
XrdXmlMetaLink Class Reference

#include <XrdXmlMetaLink.hh>

+ Collaboration diagram for XrdXmlMetaLink:

Public Member Functions

 XrdXmlMetaLink (const char *protos="root:xroot:", const char *rdprot="xroot:", const char *rdhost=0, const char *encode=0)
 
 ~XrdXmlMetaLink ()
 Destructor. More...
 
XrdOucFileInfoConvert (const char *fbuff, int blen=0)
 
XrdOucFileInfo ** ConvertAll (const char *fbuff, int &count, int blen=0)
 
const char * GetStatus (int &ecode)
 

Static Public Member Functions

static void DeleteAll (XrdOucFileInfo **vecp, int vecn)
 

Detailed Description

The XrdXmlMetaLink object provides a uniform interface to convert metalink XML specifications to one or more XrdOucFileInfo objects. This object does not do a rigorous syntactic check of the metalink specification. Specifications that technically violate RFC 5854 (v4 metalinks) or the metalink.org v3 metalinks may be accepted and yield valid information.

Definition at line 46 of file XrdXmlMetaLink.hh.

Constructor & Destructor Documentation

◆ XrdXmlMetaLink()

XrdXmlMetaLink::XrdXmlMetaLink ( const char *  protos = "root:xroot:",
const char *  rdprot = "xroot:",
const char *  rdhost = 0,
const char *  encode = 0 
)
inline

Constructor

Parameters
protosPointer to the list of desired protocols. Each protocol ends with a colon. They are specified without embedded spaces. Only urls using one of the listed protocols is returned. A nil pointer returns all urls regardless of the protocol.
rdprotThe protocol to be used when constructing the global file entry. If nil, the first protocol in protos is used. If nil, a global file is not constructed.
rdhostThe "<host>[<port>]" to use when constructing the global file. A global file entry is constructed only if rdhost is specified and a protocol is available, and a global file element exists in the xml file.
encodeSpecifies the xml encoding. Currently, only UTF-8 is is supported and is signified by a nil pointer.

Definition at line 136 of file XrdXmlMetaLink.hh.

136  :xroot:",
137  const char *rdprot="xroot:",
138  const char *rdhost=0,
139  const char *encode=0
140  ) : reader(0),
141  fileList(0), lastFile(0), currFile(0),
142  prots(protos ? strdup(protos) : 0),
143  encType(encode ? strdup(encode) : 0),
144  rdProt(rdprot), rdHost(rdhost),
145  fileCnt(0), eCode(0),
146  doAll(false), noUrl(true)
147  {*eText = 0; *tmpFn = 0;}

◆ ~XrdXmlMetaLink()

XrdXmlMetaLink::~XrdXmlMetaLink ( )
inline

Destructor.

Definition at line 153 of file XrdXmlMetaLink.hh.

153  {if (prots) free(prots);
154  if (encType) free(encType);
155  }

Member Function Documentation

◆ Convert()

XrdOucFileInfo * XrdXmlMetaLink::Convert ( const char *  fbuff,
int  blen = 0 
)

Convert an XML metalink specification to a file info object. Only the first file entry is converted (see ConvertAll()).

Parameters
fbuffPointer to the filepath that contains the metalink specification when blen is 0. Otherwise, fbuff points to a memory buffer of length blen containing the specification.
blenLength of the buffer. When <=0, the first argument is a file path. Otherwise, it is a memory buffer of length blen whose contents are written into a file in /tmp, converted, and then deleted.
Returns
Pointer to the corresponding file info object upon success. Otherwise, a null pointer is returned indicating that the metalink specification was invalid or had no required protocols. Use the GetStatus() method to obtain the description of the problem.

Definition at line 104 of file XrdXmlMetaLink.cc.

105 {
106  static const char *mlV3NS = "http://www.metalinker.org/";
107  static const char *mlV4NS = "urn:ietf:params:xml:ns:metalink";
108  static const char *mlV3[] = {"metalink", "files", 0};
109  static const char *mTag[] = {"", "metalink", 0};
110  static const char *mAtr[] = {"xmlns", 0};
111  const char *scope = "metalink";
112  char *mVal[] = {0};
113  CleanUp onReturn;
114  XrdOucFileInfo *fP;
115  const char *gLFN;
116  char *colon, gHdr[272];
117  bool chkG;
118 
119 // If we are converting a buffer, then generate the file
120 //
121  if (blen > 0)
122  {if (!PutFile(fname, blen)) return 0;
123  onReturn.delTFN = tmpFn;
124  fname = tmpFn;
125  }
126 
127 // Check if we should add a global file entry
128 //
129  if (rdHost && (rdProt || (prots && (colon = index(prots,':')))))
130  {if (!rdProt) {rdProt = prots; *(colon+1) = 0;}
131  else colon = 0;
132  snprintf(gHdr, sizeof(gHdr), "%s//%s/", rdProt, rdHost);
133  if (colon) *(colon+1) = ':';
134  chkG = true;
135  } else chkG = false;
136 
137 // Get a file reader
138 //
139  if (!(reader = XrdXmlReader::GetReader(fname, encType)))
140  {eCode = errno;
141  snprintf(eText, sizeof(eText), "%s trying to read %s",
142  (errno ? XrdSysE2T(errno) : "Unknown error"), fname);
143  return 0;
144  }
145 
146 // Make sure we delete the reader should we return
147 //
148  onReturn.delRDR = &reader;
149 
150 // We must find the metalink tag
151 //
152  if (!reader->GetElement(mTag, true))
153  {GetRdrError("looking for 'metalink' tag");
154  return 0;
155  }
156 
157 // The input can be in metalink 3 or metalink 4 format. The metalink tag will
158 // tell us which one it is. It better be in the document with the xmlns attribute
159 //
160  if (!reader->GetAttributes(mAtr, mVal))
161  {strcpy(eText, "Required metalink tag attribute 'xmlns' not found");
162  eCode = ENOMSG;
163  return 0;
164  }
165 
166 // The namespace tells us what format we are using here. For v3 formt we must
167 // alignh ourselves on the "files" tag. There can only be one of those present.
168 //
169  if (!strcmp(mVal[0], mlV3NS))
170  {if (!reader->GetElement(mlV3, true))
171  GetRdrError("looking for 'files' tag");
172  scope = "files";
173  }
174  else if ( strcmp((const char *)mVal[0], mlV4NS))
175  {strcpy(eText, "Metalink format not supported");
176  eCode = EPFNOSUPPORT;
177  }
178 
179 // Check if can continue
180 //
181  free(mVal[0]);
182  if (eCode) return 0;
183 
184 // Get one or more files
185 //
186  currFile = 0; fileCnt = 0; noUrl = true;
187  do{if (!GetFile(scope)) break;
188  currFile = new XrdOucFileInfo;
189  if (GetFileInfo("file"))
190  {if (lastFile) lastFile ->nextFile = currFile;
191  else fileList = currFile;
192  lastFile = currFile;
193  if (chkG && (gLFN = currFile->GetLfn()))
194  {char lfnBuff[2048];
195  snprintf(lfnBuff, sizeof(lfnBuff), "%s%s", gHdr, gLFN);
196  currFile->AddUrl(lfnBuff, 0, INT_MAX);
197  currFile->AddProtocol(rdProt);
198  }
199  currFile = 0;
200  fileCnt++; noUrl = true;
201  }
202  } while(doAll);
203 
204 // The loop ends when we cannot find a file tag. So, the current file is invalid
205 //
206  if (currFile) {delete currFile; currFile = 0;}
207 
208 // Check if we have any files at all
209 //
210  if (!fileCnt)
211  {strcpy(eText, "No applicable urls specified for the file entry");
212  eCode = EDESTADDRREQ;
213  }
214 
215 // If this is an all call then return to execute the postantem
216 //
217  fP = fileList; lastFile = fileList = 0;
218  if (doAll) return fP;
219 
220 // Check if we have clean status. If not, undo all we have and return failure
221 //
222  if (!eCode) return fP;
223  if (fP) delete fP;
224  return 0;
225 }
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
XrdOucFileInfo * nextFile
Link field to simply miltiple file processing.
void AddProtocol(const char *protname)
void AddUrl(const char *url, const char *cntry=0, int prty=0, bool fifo=true)
const char * GetLfn()
static XrdXmlReader * GetReader(const char *fname, const char *enc=0, const char *impl=0)
Definition: XrdXmlReader.cc:43
virtual int GetElement(const char **ename, bool reqd=false)=0
virtual bool GetAttributes(const char **aname, char **aval)=0

References XrdOucFileInfo::AddProtocol(), XrdOucFileInfo::AddUrl(), XrdXmlReader::GetAttributes(), XrdXmlReader::GetElement(), XrdOucFileInfo::GetLfn(), XrdXmlReader::GetReader(), XrdOucFileInfo::nextFile, and XrdSysE2T().

Referenced by ConvertAll().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ConvertAll()

XrdOucFileInfo ** XrdXmlMetaLink::ConvertAll ( const char *  fbuff,
int &  count,
int  blen = 0 
)

Convert an XML metalink specification to a file info object. All file entries are converted.

Parameters
fbuffPointer to the filepath that contains the metalink specification when blen is 0. Otherwise, fbuff points to a memory buffer of length blen containing the specification.
countPlace where the number of array elements is returned.
blenLength of the buffer. When <=0, the first argument is a file path. Otherwise, it is a memory buffer of length blen whose contents are written into a file in /tmp, converted, and then deleted.
Returns
Pointer to the array of corresponding fil info objects upon success. Otherwise, Otherwise, a null pointer is returned indicating that the metalink specification was invalid or had no required protocols. Use the GetStatus() method to obtain the description of the problem. Be aware that you must first delete each file info object before deleting the array. You can do this via DeleteAll().

Definition at line 231 of file XrdXmlMetaLink.cc.

233 {
234  CleanUp onReturn;
235  XrdOucFileInfo *fP, **fvP;
236 
237 // Indicate this is a call from here
238 //
239  doAll = true;
240  count = 0;
241 
242 // If we are converting a buffer, then generate the file
243 //
244  if (blen > 0)
245  {if (!PutFile(fname, blen)) return 0;
246  onReturn.delTFN = tmpFn;
247  fname = tmpFn;
248  }
249 
250 // Perform the conversion
251 //
252  if (!(fP = Convert(fname))) return 0;
253 
254 // Check if we have clean status, if not return nothing
255 //
256  if (eCode)
257  {XrdOucFileInfo *fnP = fP->nextFile;
258  while((fP = fnP))
259  {fnP = fP->nextFile;
260  delete fP;
261  }
262  return 0;
263  }
264 
265 // Return a vector of the file info objects
266 //
267  fvP = new XrdOucFileInfo* [fileCnt];
268  for (int i = 0; i < fileCnt; i++) {fvP[i] = fP; fP = fP->nextFile;}
269  count = fileCnt;
270  return fvP;
271 }

References Convert(), and XrdOucFileInfo::nextFile.

+ Here is the call graph for this function:

◆ DeleteAll()

void XrdXmlMetaLink::DeleteAll ( XrdOucFileInfo **  vecp,
int  vecn 
)
static

Delete a vector of file info objects and the vector itself as well.

Parameters
vecpPointer to the array.
vecnNumber of elements in the vector.

Definition at line 277 of file XrdXmlMetaLink.cc.

278 {
279 // Delete each object in the vector
280 //
281  for (int i = 0; i < vecn; i++)
282  delete vecp[i];
283 
284 // Now delete the vector
285 //
286  delete []vecp;
287 }

◆ GetStatus()

const char* XrdXmlMetaLink::GetStatus ( int &  ecode)
inline

Obtain ending status of previous conversion.

Parameters
ecodePlace to return the error code, if any.
Returns
Pointer to the error text describing the error. The string becomes invalid if Convert() is called or the object is deleted. If no error was encountered, a null string is returned with ecode == 0.

Definition at line 115 of file XrdXmlMetaLink.hh.

115 {ecode = eCode; return eText;}

The documentation for this class was generated from the following files: