1
# Orthanc - A Lightweight, RESTful DICOM Store
2
# Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
3
# Department, University Hospital of Liege, Belgium
5
# This program is free software: you can redistribute it and/or
6
# modify it under the terms of the GNU Affero General Public License
7
# as published by the Free Software Foundation, either version 3 of
8
# the 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
# Affero General Public License for more details.
15
# You should have received a copy of the GNU Affero General Public License
16
# along with this program. If not, see <http://www.gnu.org/licenses/>.
27
for i in range(len(sys.argv)):
28
if not sys.argv[i].startswith('--'):
29
ARGS.append(sys.argv[i])
30
elif sys.argv[i].lower() == '--no-upcase-check':
33
if len(ARGS) < 2 or len(ARGS) % 2 != 0:
35
print ('python %s [--no-upcase-check] <TargetBaseFilename> [ <Name> <Source> ]*' % sys.argv[0])
38
TARGET_BASE_FILENAME = ARGS[1]
42
# Make sure the destination directory exists
43
os.makedirs(os.path.normpath(os.path.join(TARGET_BASE_FILENAME, '..')))
48
#####################################################################
49
## Read each resource file
50
#####################################################################
55
re.search('[A-Z]', s) != None):
56
raise Exception("Path in a directory with an upcase letter: %s" % s)
62
while i < len(SOURCES):
63
resourceName = SOURCES[i].upper()
64
pathName = SOURCES[i + 1]
66
if not os.path.exists(pathName):
67
raise Exception("Non existing path: %s" % pathName)
69
if resourceName in resources:
70
raise Exception("Twice the same resource: " + resourceName)
72
if os.path.isdir(pathName):
73
# The resource is a directory: Recursively explore its files
75
for root, dirs, files in os.walk(pathName):
76
base = os.path.relpath(root, pathName)
78
# Fix issue #24 (Build fails on OSX when directory has .DS_Store files):
79
# Ignore folders whose name starts with a dot (".")
80
if base.find('/.') != -1:
81
print('Ignoring folder: %s' % root)
85
if f.find('~') == -1: # Ignore Emacs backup files
89
r = os.path.join(base, f)
92
r = '/' + r.replace('\\', '/')
94
raise Exception("Twice the same filename (check case): " + r)
97
'Filename' : os.path.join(root, f),
102
resources[resourceName] = {
103
'Type' : 'Directory',
107
elif os.path.isfile(pathName):
108
resources[resourceName] = {
111
'Filename' : pathName
116
raise Exception("Not a regular file, nor a directory: " + pathName)
120
#pprint.pprint(resources)
123
#####################################################################
125
#####################################################################
127
header = open(TARGET_BASE_FILENAME + '.h', 'w')
135
namespace OrthancPlugins
137
namespace EmbeddedResources
144
for name in resources:
145
if resources[name]['Type'] == 'File':
150
header.write(' %s' % name)
155
enum DirectoryResourceId
160
for name in resources:
161
if resources[name]['Type'] == 'Directory':
166
header.write(' %s' % name)
171
const void* GetFileResourceBuffer(FileResourceId id);
172
size_t GetFileResourceSize(FileResourceId id);
173
void GetFileResource(std::string& result, FileResourceId id);
175
const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path);
176
size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path);
177
void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path);
179
void ListResources(std::list<std::string>& result, DirectoryResourceId id);
187
#####################################################################
188
## Write the resource content in the .cpp source
189
#####################################################################
191
PYTHON_MAJOR_VERSION = sys.version_info[0]
193
def WriteResource(cpp, item):
194
cpp.write(' static const uint8_t resource%dBuffer[] = {' % item['Index'])
196
f = open(item['Filename'], "rb")
200
# http://stackoverflow.com/a/1035360
203
if PYTHON_MAJOR_VERSION == 2:
215
raise Exception("Internal error")
217
cpp.write("0x%02x" % c)
221
cpp.write(' static const size_t resource%dSize = %d;\n' % (item['Index'], pos))
224
cpp = open(TARGET_BASE_FILENAME + '.cpp', 'w')
233
namespace OrthancPlugins
235
namespace EmbeddedResources
237
""" % (os.path.basename(TARGET_BASE_FILENAME)))
240
for name in resources:
241
if resources[name]['Type'] == 'File':
242
WriteResource(cpp, resources[name])
244
for f in resources[name]['Files']:
245
WriteResource(cpp, resources[name]['Files'][f])
249
#####################################################################
250
## Write the accessors to the file resources in .cpp
251
#####################################################################
254
const void* GetFileResourceBuffer(FileResourceId id)
259
for name in resources:
260
if resources[name]['Type'] == 'File':
261
cpp.write(' case %s:\n' % name)
262
cpp.write(' return resource%dBuffer;\n' % resources[name]['Index'])
266
throw std::runtime_error("Parameter out of range");
270
size_t GetFileResourceSize(FileResourceId id)
276
for name in resources:
277
if resources[name]['Type'] == 'File':
278
cpp.write(' case %s:\n' % name)
279
cpp.write(' return resource%dSize;\n' % resources[name]['Index'])
283
throw std::runtime_error("Parameter out of range");
290
#####################################################################
291
## Write the accessors to the directory resources in .cpp
292
#####################################################################
295
const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path)
301
for name in resources:
302
if resources[name]['Type'] == 'Directory':
303
cpp.write(' case %s:\n' % name)
305
for path in resources[name]['Files']:
306
cpp.write(' if (!strcmp(path, "%s"))\n' % path)
307
cpp.write(' return resource%dBuffer;\n' % resources[name]['Files'][path]['Index'])
308
cpp.write(' throw std::runtime_error("Unknown path in a directory resource");\n\n')
310
cpp.write(""" default:
311
throw std::runtime_error("Parameter out of range");
315
size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path)
321
for name in resources:
322
if resources[name]['Type'] == 'Directory':
323
cpp.write(' case %s:\n' % name)
325
for path in resources[name]['Files']:
326
cpp.write(' if (!strcmp(path, "%s"))\n' % path)
327
cpp.write(' return resource%dSize;\n' % resources[name]['Files'][path]['Index'])
328
cpp.write(' throw std::runtime_error("Unknown path in a directory resource");\n\n')
330
cpp.write(""" default:
331
throw std::runtime_error("Parameter out of range");
339
#####################################################################
340
## List the resources in a directory
341
#####################################################################
344
void ListResources(std::list<std::string>& result, DirectoryResourceId id)
352
for name in resources:
353
if resources[name]['Type'] == 'Directory':
354
cpp.write(' case %s:\n' % name)
355
for path in sorted(resources[name]['Files']):
356
cpp.write(' result.push_back("%s");\n' % path)
357
cpp.write(' break;\n\n')
359
cpp.write(""" default:
360
throw std::runtime_error("Parameter out of range");
368
#####################################################################
369
## Write the convenience wrappers in .cpp
370
#####################################################################
373
void GetFileResource(std::string& result, FileResourceId id)
375
size_t size = GetFileResourceSize(id);
378
memcpy(&result[0], GetFileResourceBuffer(id), size);
381
void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path)
383
size_t size = GetDirectoryResourceSize(id, path);
386
memcpy(&result[0], GetDirectoryResourceBuffer(id, path), size);