Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
ReadFile.m
Go to the documentation of this file.
1/*
2 * ReadFile.m
3 * ROOTSL
4 *
5 * Created by Fons Rademakers on 22/05/09.
6 * Copyright 2009 CERN. All rights reserved.
7 *
8 */
9
10#include <stdio.h>
11#include <fcntl.h>
12#include <sys/types.h>
13#include <sys/uio.h>
14#include <unistd.h>
15#include <stdlib.h>
16#include <strings.h>
17#include <errno.h>
18
19#import <Foundation/Foundation.h>
20
21
22#if defined(__i386__)
23# define R__BYTESWAP
24#endif
25#if defined(__x86_64__)
26# define R__BYTESWAP
27#endif
28
29
30struct FileHeader_t {
31 long long end;
32 long long seekFree;
33 long long seekInfo;
34 long long seekKeys;
35 int version;
36 int begin;
37 int compress;
38 int nbytesName;
39 int dateC;
40 int timeC;
41 int dateM;
42 int timeM;
43 char units;
44 char *uuid;
45 char *title;
46 const char *name;
47};
48
49
50static void FromBufChar(char **buf, char *x)
51{
52 // Read a char from the buffer and advance the buffer.
53
54 *x = **buf;
55 *buf += 1;
56}
57
58static void FromBufShort(char **buf, short *x)
59{
60 // Read a short from the buffer and advance the buffer.
61
62#ifdef R__BYTESWAP
63 char *sw = (char *)x;
64 sw[0] = (*buf)[1];
65 sw[1] = (*buf)[0];
66#else
67 memcpy(x, *buf, sizeof(short));
68#endif
69 *buf += sizeof(short);
70}
71
72static void FromBufInt(char **buf, int *x)
73{
74 // Read an int from the buffer and advance the buffer.
75
76#ifdef R__BYTESWAP
77 char *sw = (char *)x;
78 sw[0] = (*buf)[3];
79 sw[1] = (*buf)[2];
80 sw[2] = (*buf)[1];
81 sw[3] = (*buf)[0];
82#else
83 memcpy(x, *buf, sizeof(int));
84#endif
85 *buf += sizeof(int);
86}
87
88static void FromBufLL(char **buf, long long *x)
89{
90 // Read a long long from the buffer and advance the buffer.
91
92#ifdef R__BYTESWAP
93 char *sw = (char *)x;
94 sw[0] = (*buf)[7];
95 sw[1] = (*buf)[6];
96 sw[2] = (*buf)[5];
97 sw[3] = (*buf)[4];
98 sw[4] = (*buf)[3];
99 sw[5] = (*buf)[2];
100 sw[6] = (*buf)[1];
101 sw[7] = (*buf)[0];
102#else
103 memcpy(x, *buf, sizeof(long long));
104#endif
105 *buf += sizeof(long long);
106}
107
108static void FromBufUUID(char **buf, char **uuid, int versiondir)
109{
110 // Read UUID from the buffer and return it as string in uuid.
111 // Returned string must be freed by the caller.
112 // We'll never come here if version < 2.
113
114 unsigned int timeLow;
115 unsigned short version, timeMid, timeHiAndVersion;
116 unsigned char clockSeqHiAndReserved, clockSeqLow, node[6];
117
118 if (versiondir > 2)
119 FromBufShort(buf, (short*)&version); //version
120 FromBufInt(buf, (int*)&timeLow);
121 FromBufShort(buf, (short*)&timeMid);
122 FromBufShort(buf, (short*)&timeHiAndVersion);
123 FromBufChar(buf, (char*)&clockSeqHiAndReserved);
124 FromBufChar(buf, (char*)&clockSeqLow);
125 int i;
126 for (i = 0; i < 6; i++)
127 FromBufChar(buf, (char*)&node[i]);
128
129 *uuid = malloc(40);
130 sprintf(*uuid, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
131 timeLow, timeMid, timeHiAndVersion, clockSeqHiAndReserved,
132 clockSeqLow, node[0], node[1], node[2], node[3], node[4],
133 node[5]);
134}
135
136static void FromBufStr(char **buf, char **str)
137{
138 // Read string from the buffer and return it as string in str.
139 // Returned string must be freed by the caller.
140
141 unsigned char nwh;
142 int nchars;
143
144 FromBufChar(buf, (char*)&nwh);
145 if (nwh == 255)
146 FromBufInt(buf, &nchars);
147 else
148 nchars = nwh;
149
150 int i;
151 *str = malloc(nchars+1);
152 for (i = 0; i < nchars; i++)
153 FromBufChar(buf, &(*str)[i]);
154 (*str)[nchars] = '\0';
155}
156
157static void GetDateAndTime(unsigned int datetime, int *date, int *time)
158{
159 // Function that returns the date and time. The input is
160 // in TDatime format (as obtained via TDatime::Get()).
161 // Date is returned in the format 950223 February 23 1995.
162 // Time is returned in the format 102459 10h 24m 59s.
163
164 unsigned int year = datetime>>26;
165 unsigned int month = (datetime<<6)>>28;
166 unsigned int day = (datetime<<10)>>27;
167 unsigned int hour = (datetime<<15)>>27;
168 unsigned int min = (datetime<<20)>>26;
169 unsigned int sec = (datetime<<26)>>26;
170 *date = 10000*(year+1995) + 100*month + day;
171 *time = 10000*hour + 100*min + sec;
172}
173
174static int ReadBuffer(int fd, char *buffer, int len)
175{
176 ssize_t siz;
177 while ((siz = read(fd, buffer, len)) < 0 && errno == EINTR)
178 errno = 0;
179 return (int)siz;
180}
181
182static int ReadHeader(int fd, struct FileHeader_t *fh, NSMutableSet *titleSet)
183{
184 // Read ROOT file header structure.
185 // Returns -1 in case of error, 0 otherwise.
186
187 const int len = 300;
188 char *header = malloc(len);
189
190 if (ReadBuffer(fd, header, len) != len) {
191 free(header);
192 return -1;
193 }
194
195 if (strncmp(header, "root", 4)) {
196 free(header);
197 return -1;
198 }
199
200 char *buffer = header + 4; // skip the "root" file identifier
201
202 FromBufInt(&buffer, &fh->version);
203 FromBufInt(&buffer, &fh->begin);
204
205 int dummy;
206 long long dummyll;
207
208 if (fh->version < 1000000) {
209 // < 2GB file
210 int seekfree, seekinfo;
211 FromBufInt(&buffer, &dummy); fh->end = (long long) dummy;
212 FromBufInt(&buffer, &seekfree); fh->seekFree = (long long) seekfree;
213 FromBufInt(&buffer, &dummy); // nbytes free
214 FromBufInt(&buffer, &dummy); // nfree
215 FromBufInt(&buffer, &fh->nbytesName);
216 FromBufChar(&buffer, &fh->units);
217 FromBufInt(&buffer, &fh->compress);
218 FromBufInt(&buffer, &seekinfo); fh->seekInfo = (long long) seekinfo;
219 FromBufInt(&buffer, &dummy); // nbytes info
220 } else {
221 // > 2GB file
222 FromBufLL(&buffer, &fh->end);
223 FromBufLL(&buffer, &fh->seekFree);
224 FromBufInt(&buffer, &dummy); // nbytes free
225 FromBufInt(&buffer, &dummy); // nfree
226 FromBufInt(&buffer, &fh->nbytesName);
227 FromBufChar(&buffer, &fh->units);
228 FromBufInt(&buffer, &fh->compress);
229 FromBufLL(&buffer, &fh->seekInfo);
230 FromBufInt(&buffer, &dummy); // nbytes info
231 }
232
233 int nk = sizeof(int)+sizeof(short)+2*sizeof(int)+2*sizeof(short)+2*sizeof(int);
234 int nbytes = fh->nbytesName + (22 + 2*sizeof(int) + 18); //nbytesName + TDirectoryFile::Sizeof();
235 if (fh->version >= 40000)
236 nbytes += 12;
237
238 if (nbytes + fh->begin > 300) {
239 free(header);
240 header = malloc(nbytes);
241 lseek(fd, (off_t)fh->begin, SEEK_SET);
242 if (ReadBuffer(fd, header, nbytes) != nbytes) {
243 free(header);
244 return -1;
245 }
246 buffer = header + fh->nbytesName;
247 } else {
248 buffer = header + fh->begin + fh->nbytesName;
249 nk += fh->begin;
250 }
251
252 short dversion, versiondir;
253 FromBufShort(&buffer, &dversion);
254 versiondir = dversion%1000;
255 FromBufInt(&buffer, &dummy);
256 GetDateAndTime((unsigned int)dummy, &fh->dateC, &fh->timeC);
257 FromBufInt(&buffer, &dummy);
258 GetDateAndTime((unsigned int)dummy, &fh->dateM, &fh->timeM);
259 FromBufInt(&buffer, &dummy); // nbytes keys
260 FromBufInt(&buffer, &dummy); // nbytes name
261 if (dversion > 1000) {
262 FromBufLL(&buffer, &dummyll); // seek dir
263 FromBufLL(&buffer, &dummyll); // seek parent
264 FromBufLL(&buffer, &fh->seekKeys);
265 } else {
266 int skeys;
267 FromBufInt(&buffer, &dummy); // seek dir
268 FromBufInt(&buffer, &dummy); // seek parent
269 FromBufInt(&buffer, &skeys); fh->seekKeys = (long long)skeys;
270 }
271 if (versiondir > 1)
272 FromBufUUID(&buffer, &fh->uuid, versiondir);
273 else
274 fh->uuid = strdup("-");
275
276 buffer = header + nk;
277 char *str;
278 FromBufStr(&buffer, &str); free(str); // "TFile"
279 FromBufStr(&buffer, &str); free(str); // orig filename
280 FromBufStr(&buffer, &fh->title);
281
282#ifdef DEBUG
283 NSLog(@"%s: version = %d, begin = %d, end = %lld, units = %hhd, compress = %d",
284 fh->name, fh->version, fh->begin, fh->end, fh->units, fh->compress);
285#endif
286
287 [titleSet addObject: [NSString stringWithUTF8String: fh->title]];
288
289 free(header);
290
291 return 0;
292}
293
294static int ReadKeys(int fd, struct FileHeader_t *fh, NSMutableSet *nameSet, NSMutableSet *titleSet)
295{
296 // Loop over all keys and print information.
297 // Returns -1 in case of error, 0 otherwise.
298
299 int nbytes;
300 int objlen;
301 int date;
302 int time;
303 short keylen;
304 short cycle;
305 char *classname;
306 char *name;
307 char *title;
308
309 const int len = 256;
310 int nread, datime;
311 short versionkey;
312 char *header, *buffer;
313
314 long long idcur = fh->begin;
315
316 nread = len;
317 while (idcur < fh->end) {
318 again:
319 header = malloc(nread);
320 lseek(fd, (off_t)idcur, SEEK_SET);
321 if (idcur+nread > fh->end) nread = fh->end-idcur-1;
322 if (ReadBuffer(fd, header, nread) != nread) {
323 free(header);
324 return -1;
325 }
326 buffer = header;
327 FromBufInt(&buffer, &nbytes);
328 if (!nbytes) {
329 // read error
330 free(header);
331 break;
332 }
333 if (nbytes < 0) {
334 // a gap
335 free(header);
336 idcur -= nbytes;
337 continue;
338 }
339
340 FromBufShort(&buffer, &versionkey);
341 FromBufInt(&buffer, &objlen);
342 FromBufInt(&buffer, &datime);
343 GetDateAndTime((unsigned int)datime, &date, &time);
344 FromBufShort(&buffer, &keylen);
345 FromBufShort(&buffer, &cycle);
346 if (versionkey > 1000) {
347 long long dummyll;
348 FromBufLL(&buffer, &dummyll); // seekkey
349 FromBufLL(&buffer, &dummyll); // seekpdir
350 } else {
351 int dummy;
352 FromBufInt(&buffer, &dummy); // seekkey
353 FromBufInt(&buffer, &dummy); // seekpdir
354 }
355 if (keylen > nread) {
356 free(header);
357 nread = keylen;
358 goto again;
359 }
360 FromBufStr(&buffer, &classname);
361 FromBufStr(&buffer, &name);
362 FromBufStr(&buffer, &title);
363 if (idcur == fh->seekFree) {
364 free(classname);
365 classname = strdup("FreeSegments");
366 name[0] = '\0';
367 title[0] = '\0';
368 }
369 if (idcur == fh->seekInfo) {
370 free(classname);
371 classname = strdup("StreamerInfo");
372 name[0] = '\0';
373 title[0] = '\0';
374 }
375 if (idcur == fh->seekKeys) {
376 free(classname);
377 classname = strdup("KeysList");
378 name[0] = '\0';
379 title[0] = '\0';
380 }
381 float cx;
382 if (objlen != nbytes-keylen)
383 cx = (float)(objlen+keylen)/(float)nbytes;
384 else
385 cx = 1.0;
386
387 if (strlen(name))
388 [nameSet addObject: [NSString stringWithUTF8String: name]];
389 if (strlen(title))
390 [titleSet addObject: [NSString stringWithUTF8String: title]];
391
392 free(classname);
393 free(name);
394 free(title);
395 free(header);
396
397 nread = len;
398
399 idcur += nbytes;
400 }
401
402 return 0;
403}
404
405int ReadFile(NSString *fullPath, NSMutableSet *nameSet, NSMutableSet *titleSet)
406{
407 // Read ROOT file structure for specified file.
408 // Returns -1 in case of error, 0 otherwise.
409
410 struct FileHeader_t fh;
411 fh.name = [fullPath UTF8String];
412 int fd = open(fh.name, O_RDONLY, 0644);
413 if (fd == -1)
414 return -1;
415
416 if (ReadHeader(fd, &fh, titleSet) == -1) {
417 close(fd);
418 return -1;
419 }
420
421 if (ReadKeys(fd, &fh, nameSet, titleSet) == -1) {
422 free(fh.uuid);
423 free(fh.title);
424 close(fd);
425 return -1;
426 }
427
428 free(fh.uuid);
429 free(fh.title);
430
431 close(fd);
432
433 return 0;
434}
char name[80]
Definition TGX11.cxx:148
#define SEEK_SET
Definition ZIP.h:47
#define free
Definition civetweb.c:1578
#define malloc
Definition civetweb.c:1575
subroutine node(ivo, nuserm, iposp)
Definition g2root.f:833
Double_t x[n]
Definition legend1.C:17
double read()
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
static void FromBufInt(char **buf, int *x)
Definition ReadFile.m:73
static void FromBufChar(char **buf, char *x)
Definition ReadFile.m:51
static void FromBufShort(char **buf, short *x)
Definition ReadFile.m:59
static void FromBufUUID(char **buf, char **uuid, int versiondir)
Definition ReadFile.m:109
static int ReadHeader(int fd, struct FileHeader_t *fh, NSMutableString *html)
Definition ReadFile.m:183
static void GetDateAndTime(unsigned int datetime, int *date, int *time)
Definition ReadFile.m:158
static void FromBufLL(char **buf, long long *x)
Definition ReadFile.m:89
static int ReadBuffer(int fd, char *buffer, int len)
Definition ReadFile.m:175
static void FromBufStr(char **buf, char **str)
Definition ReadFile.m:137
int ReadFile(NSString *fullPath, NSMutableSet *nameSet, NSMutableSet *titleSet)
Definition ReadFile.m:405
static int ReadKeys(int fd, struct FileHeader_t *fh, NSMutableSet *nameSet, NSMutableSet *titleSet)
Definition ReadFile.m:294
long long end
Definition ReadFile.m:32
long long seekFree
Definition ReadFile.m:33
char * uuid
Definition ReadFile.m:45
int nbytesName
Definition ReadFile.m:39
char * title
Definition ReadFile.m:46
long long seekInfo
Definition ReadFile.m:34
long long seekKeys
Definition ReadFile.m:35
const char * name
Definition ReadFile.m:47
Int_t year
Int_t month
Int_t day