2 * This file is part of NumptyPhysics
3 * Copyright (C) 2008 Tim Edmonds
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
18 #include <sys/types.h>
27 static int rankFromPath( const string
& p
, int defaultrank
=9999 )
29 const char *c
= p
.data();
30 size_t i
= p
.rfind(Os::pathSep
);
31 if ( i
!= string::npos
) {
35 while ( *c
>='0' && *c
<='9' ) {
36 rank
= rank
*10 + (*c
)-'0';
45 Levels::Levels( int numFiles
, const char** names
)
47 for ( int d
=0;d
<numFiles
;d
++ ) {
52 bool Levels::addPath( const char* path
)
54 int len
= strlen( path
);
55 if ( strcasecmp( path
+len
-4, ".npz" )==0 ) {
56 scanCollection( string(path
), rankFromPath(path
) );
57 } else if ( strcasecmp( path
+len
-4, ".nph" )==0 ) {
58 addLevel( path
, rankFromPath(path
) );
60 DIR *dir
= opendir( path
);
63 while ( (entry
= readdir( dir
)) != NULL
) {
64 if ( entry
->d_name
[0] != '.' ) {
67 full
+= entry
->d_name
;
68 //DANGER - recursion may not halt for linked dirs
69 addPath( full
.c_str() );
74 printf("bogus level path %s\n",path
);
80 bool Levels::addLevel( const string
& file
, int rank
, int index
)
82 LevelDesc
*e
= new LevelDesc( file
, rank
, index
);
83 for ( int i
=0; i
<m_levels
.size(); i
++ ) {
84 if ( m_levels
[i
]->file
== file
85 && m_levels
[i
]->index
== index
) {
86 printf("addLevel %s already present!\n",file
.c_str());
88 } else if ( m_levels
[i
]->rank
> rank
) {
89 printf("addLevel %s at %d\n",file
.c_str(),i
);
94 printf("top level %s\n",file
.c_str());
100 bool Levels::scanCollection( const std::string
& file
, int rank
)
103 printf("found collection %s with %d levels\n",file
.c_str(),zf
.numEntries());
104 for ( int i
=0; i
<zf
.numEntries(); i
++ ) {
105 addLevel( file
, rankFromPath(zf
.entryName(i
),rank
), i
);
110 int Levels::numLevels()
112 return m_levels
.size();
116 int Levels::load( int i
, unsigned char* buf
, int bufLen
)
119 if ( i
< m_levels
.size() ) {
120 if ( m_levels
[i
]->index
>= 0 ) {
121 ZipFile
zf( m_levels
[i
]->file
.c_str() );
122 if ( m_levels
[i
]->index
< zf
.numEntries() ) {
123 unsigned char* d
= zf
.extract( m_levels
[i
]->index
, &l
);
124 if ( d
&& l
<= bufLen
) {
129 FILE *f
= fopen( m_levels
[i
]->file
.c_str(), "rt" );
131 l
= fread( buf
, 1, bufLen
, f
);
137 throw "invalid level index";
141 std::string
Levels::levelName( int i
)
143 std::string s
= "end";
144 if ( i
< m_levels
.size() ) {
145 if ( m_levels
[i
]->index
>= 0 ) {
146 ZipFile
zf( m_levels
[i
]->file
.c_str() );
147 s
= zf
.entryName( m_levels
[i
]->index
);
149 s
= m_levels
[i
]->file
;
152 size_t j
= s
.rfind(Os::pathSep
);
153 size_t k
= s
.rfind('.');
154 return s
.substr(j
+1,k
-j
-1);
158 const std::string
& Levels::levelFile( int i
)
160 if ( i
< m_levels
.size() ) {
161 return m_levels
[i
]->file
;
163 throw "invalid level index";
168 int Levels::findLevel( const char *file
)
170 for ( int i
=0; i
<m_levels
.size(); i
++ ) {
171 if ( m_levels
[i
]->file
== file
) {