~ubuntu-branches/ubuntu/wily/orthanc-postgresql/wily

« back to all changes in this revision

Viewing changes to Resources/EmbedResources.py

  • Committer: Package Import Robot
  • Author(s): Sebastien Jodogne, Sebastien Jodogne, Karsten Hilbert
  • Date: 2015-08-03 09:23:28 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20150803092328-swn3mnpj0fz34v42
Tags: 1.2-1
[ Sebastien Jodogne ]
* New upstream version

[ Karsten Hilbert ]
* Enhancements for README.Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Orthanc - A Lightweight, RESTful DICOM Store
2
 
# Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
3
 
# Department, University Hospital of Liege, Belgium
4
 
#
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.
9
 
#
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.
14
 
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/>.
17
 
 
18
 
 
19
 
import sys
20
 
import os
21
 
import os.path
22
 
import pprint
23
 
import re
24
 
 
25
 
UPCASE_CHECK = True
26
 
ARGS = []
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':
31
 
        UPCASE_CHECK = False
32
 
 
33
 
if len(ARGS) < 2 or len(ARGS) % 2 != 0:
34
 
    print ('Usage:')
35
 
    print ('python %s [--no-upcase-check] <TargetBaseFilename> [ <Name> <Source> ]*' % sys.argv[0])
36
 
    exit(-1)
37
 
 
38
 
TARGET_BASE_FILENAME = ARGS[1]
39
 
SOURCES = ARGS[2:]
40
 
 
41
 
try:
42
 
    # Make sure the destination directory exists
43
 
    os.makedirs(os.path.normpath(os.path.join(TARGET_BASE_FILENAME, '..')))
44
 
except:
45
 
    pass
46
 
 
47
 
 
48
 
#####################################################################
49
 
## Read each resource file
50
 
#####################################################################
51
 
 
52
 
def CheckNoUpcase(s):
53
 
    global UPCASE_CHECK
54
 
    if (UPCASE_CHECK and
55
 
        re.search('[A-Z]', s) != None):
56
 
        raise Exception("Path in a directory with an upcase letter: %s" % s)
57
 
 
58
 
resources = {}
59
 
 
60
 
counter = 0
61
 
i = 0
62
 
while i < len(SOURCES):
63
 
    resourceName = SOURCES[i].upper()
64
 
    pathName = SOURCES[i + 1]
65
 
 
66
 
    if not os.path.exists(pathName):
67
 
        raise Exception("Non existing path: %s" % pathName)
68
 
 
69
 
    if resourceName in resources:
70
 
        raise Exception("Twice the same resource: " + resourceName)
71
 
    
72
 
    if os.path.isdir(pathName):
73
 
        # The resource is a directory: Recursively explore its files
74
 
        content = {}
75
 
        for root, dirs, files in os.walk(pathName):
76
 
            base = os.path.relpath(root, pathName)
77
 
 
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)
82
 
                continue
83
 
 
84
 
            for f in files:
85
 
                if f.find('~') == -1:  # Ignore Emacs backup files
86
 
                    if base == '.':
87
 
                        r = f
88
 
                    else:
89
 
                        r = os.path.join(base, f)
90
 
 
91
 
                    CheckNoUpcase(r)
92
 
                    r = '/' + r.replace('\\', '/')
93
 
                    if r in content:
94
 
                        raise Exception("Twice the same filename (check case): " + r)
95
 
 
96
 
                    content[r] = {
97
 
                        'Filename' : os.path.join(root, f),
98
 
                        'Index' : counter
99
 
                        }
100
 
                    counter += 1
101
 
 
102
 
        resources[resourceName] = {
103
 
            'Type' : 'Directory',
104
 
            'Files' : content
105
 
            }
106
 
 
107
 
    elif os.path.isfile(pathName):
108
 
        resources[resourceName] = {
109
 
            'Type' : 'File',
110
 
            'Index' : counter,
111
 
            'Filename' : pathName
112
 
            }
113
 
        counter += 1
114
 
 
115
 
    else:
116
 
        raise Exception("Not a regular file, nor a directory: " + pathName)
117
 
 
118
 
    i += 2
119
 
 
120
 
#pprint.pprint(resources)
121
 
 
122
 
 
123
 
#####################################################################
124
 
## Write .h header
125
 
#####################################################################
126
 
 
127
 
header = open(TARGET_BASE_FILENAME + '.h', 'w')
128
 
 
129
 
header.write("""
130
 
#pragma once
131
 
 
132
 
#include <string>
133
 
#include <list>
134
 
 
135
 
namespace OrthancPlugins
136
 
{
137
 
  namespace EmbeddedResources
138
 
  {
139
 
    enum FileResourceId
140
 
    {
141
 
""")
142
 
 
143
 
isFirst = True
144
 
for name in resources:
145
 
    if resources[name]['Type'] == 'File':
146
 
        if isFirst:
147
 
            isFirst = False
148
 
        else:    
149
 
            header.write(',\n')
150
 
        header.write('      %s' % name)
151
 
 
152
 
header.write("""
153
 
    };
154
 
 
155
 
    enum DirectoryResourceId
156
 
    {
157
 
""")
158
 
 
159
 
isFirst = True
160
 
for name in resources:
161
 
    if resources[name]['Type'] == 'Directory':
162
 
        if isFirst:
163
 
            isFirst = False
164
 
        else:    
165
 
            header.write(',\n')
166
 
        header.write('      %s' % name)
167
 
 
168
 
header.write("""
169
 
    };
170
 
 
171
 
    const void* GetFileResourceBuffer(FileResourceId id);
172
 
    size_t GetFileResourceSize(FileResourceId id);
173
 
    void GetFileResource(std::string& result, FileResourceId id);
174
 
 
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);
178
 
 
179
 
    void ListResources(std::list<std::string>& result, DirectoryResourceId id);
180
 
  }
181
 
}
182
 
""")
183
 
header.close()
184
 
 
185
 
 
186
 
 
187
 
#####################################################################
188
 
## Write the resource content in the .cpp source
189
 
#####################################################################
190
 
 
191
 
PYTHON_MAJOR_VERSION = sys.version_info[0]
192
 
 
193
 
def WriteResource(cpp, item):
194
 
    cpp.write('    static const uint8_t resource%dBuffer[] = {' % item['Index'])
195
 
 
196
 
    f = open(item['Filename'], "rb")
197
 
    content = f.read()
198
 
    f.close()
199
 
 
200
 
    # http://stackoverflow.com/a/1035360
201
 
    pos = 0
202
 
    for b in content:
203
 
        if PYTHON_MAJOR_VERSION == 2:
204
 
            c = ord(b[0])
205
 
        else:
206
 
            c = b
207
 
 
208
 
        if pos > 0:
209
 
            cpp.write(', ')
210
 
 
211
 
        if (pos % 16) == 0:
212
 
            cpp.write('\n    ')
213
 
 
214
 
        if c < 0:
215
 
            raise Exception("Internal error")
216
 
 
217
 
        cpp.write("0x%02x" % c)
218
 
        pos += 1
219
 
 
220
 
    cpp.write('  };\n')
221
 
    cpp.write('    static const size_t resource%dSize = %d;\n' % (item['Index'], pos))
222
 
 
223
 
 
224
 
cpp = open(TARGET_BASE_FILENAME + '.cpp', 'w')
225
 
 
226
 
cpp.write("""
227
 
#include "%s.h"
228
 
 
229
 
#include <stdexcept>
230
 
#include <stdint.h>
231
 
#include <string.h>
232
 
 
233
 
namespace OrthancPlugins
234
 
{
235
 
  namespace EmbeddedResources
236
 
  {
237
 
""" % (os.path.basename(TARGET_BASE_FILENAME)))
238
 
 
239
 
 
240
 
for name in resources:
241
 
    if resources[name]['Type'] == 'File':
242
 
        WriteResource(cpp, resources[name])
243
 
    else:
244
 
        for f in resources[name]['Files']:
245
 
            WriteResource(cpp, resources[name]['Files'][f])
246
 
 
247
 
 
248
 
 
249
 
#####################################################################
250
 
## Write the accessors to the file resources in .cpp
251
 
#####################################################################
252
 
 
253
 
cpp.write("""
254
 
    const void* GetFileResourceBuffer(FileResourceId id)
255
 
    {
256
 
      switch (id)
257
 
      {
258
 
""")
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'])
263
 
 
264
 
cpp.write("""
265
 
      default:
266
 
        throw std::runtime_error("Parameter out of range");
267
 
      }
268
 
    }
269
 
 
270
 
    size_t GetFileResourceSize(FileResourceId id)
271
 
    {
272
 
      switch (id)
273
 
      {
274
 
""")
275
 
 
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'])
280
 
 
281
 
cpp.write("""
282
 
      default:
283
 
        throw std::runtime_error("Parameter out of range");
284
 
      }
285
 
    }
286
 
""")
287
 
 
288
 
 
289
 
 
290
 
#####################################################################
291
 
## Write the accessors to the directory resources in .cpp
292
 
#####################################################################
293
 
 
294
 
cpp.write("""
295
 
    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path)
296
 
    {
297
 
      switch (id)
298
 
      {
299
 
""")
300
 
 
301
 
for name in resources:
302
 
    if resources[name]['Type'] == 'Directory':
303
 
        cpp.write('      case %s:\n' % name)
304
 
        isFirst = True
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')
309
 
 
310
 
cpp.write("""      default:
311
 
        throw std::runtime_error("Parameter out of range");
312
 
      }
313
 
    }
314
 
 
315
 
    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path)
316
 
    {
317
 
      switch (id)
318
 
      {
319
 
""")
320
 
 
321
 
for name in resources:
322
 
    if resources[name]['Type'] == 'Directory':
323
 
        cpp.write('      case %s:\n' % name)
324
 
        isFirst = True
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')
329
 
 
330
 
cpp.write("""      default:
331
 
        throw std::runtime_error("Parameter out of range");
332
 
      }
333
 
    }
334
 
""")
335
 
 
336
 
 
337
 
 
338
 
 
339
 
#####################################################################
340
 
## List the resources in a directory
341
 
#####################################################################
342
 
 
343
 
cpp.write("""
344
 
    void ListResources(std::list<std::string>& result, DirectoryResourceId id)
345
 
    {
346
 
      result.clear();
347
 
 
348
 
      switch (id)
349
 
      {
350
 
""")
351
 
 
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')
358
 
 
359
 
cpp.write("""      default:
360
 
        throw std::runtime_error("Parameter out of range");
361
 
      }
362
 
    }
363
 
""")
364
 
 
365
 
 
366
 
 
367
 
 
368
 
#####################################################################
369
 
## Write the convenience wrappers in .cpp
370
 
#####################################################################
371
 
 
372
 
cpp.write("""
373
 
    void GetFileResource(std::string& result, FileResourceId id)
374
 
    {
375
 
      size_t size = GetFileResourceSize(id);
376
 
      result.resize(size);
377
 
      if (size > 0)
378
 
        memcpy(&result[0], GetFileResourceBuffer(id), size);
379
 
    }
380
 
 
381
 
    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path)
382
 
    {
383
 
      size_t size = GetDirectoryResourceSize(id, path);
384
 
      result.resize(size);
385
 
      if (size > 0)
386
 
        memcpy(&result[0], GetDirectoryResourceBuffer(id, path), size);
387
 
    }
388
 
  }
389
 
}
390
 
""")
391
 
cpp.close()