Skip to content

Commit 2360243

Browse files
committed
Implement lzstring compression of pcbdata
1 parent e0d413c commit 2360243

File tree

4 files changed

+541
-2
lines changed

4 files changed

+541
-2
lines changed

InteractiveHtmlBom/core/ibom.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ def process_substitutions(bom_name_format, pcb_file_name, metadata):
212212
return name + '.html'
213213

214214

215+
def get_compressed_pcbdata(pcbdata):
216+
from .lzstring import LZString
217+
218+
pcbdata_js = LZString.compress_to_utf16(json.dumps(pcbdata))
219+
pcbdata_js = json.dumps(pcbdata_js)
220+
js = "var pcbdata = JSON.parse(LZString.decompressFromUTF16({}))"
221+
return js.format(pcbdata_js)
222+
223+
215224
def generate_file(pcb_file_dir, pcb_file_name, pcbdata, config):
216225
def get_file_content(file_name):
217226
path = os.path.join(os.path.dirname(__file__), "..", "web", file_name)
@@ -230,15 +239,15 @@ def get_file_content(file_name):
230239
bom_file_dir = os.path.dirname(bom_file_name)
231240
if not os.path.isdir(bom_file_dir):
232241
os.makedirs(bom_file_dir)
233-
pcbdata_js = "var pcbdata = " + json.dumps(pcbdata)
234242
config_js = "var config = " + config.get_html_config()
235243
html = get_file_content("ibom.html")
236244
html = html.replace('///CSS///', get_file_content('ibom.css'))
237245
html = html.replace('///SPLITJS///', get_file_content('split.js'))
246+
html = html.replace('///LZ-STRING///', get_file_content('lz-string.js'))
238247
html = html.replace('///POINTER_EVENTS_POLYFILL///',
239248
get_file_content('pep.js'))
240249
html = html.replace('///CONFIG///', config_js)
241-
html = html.replace('///PCBDATA///', pcbdata_js)
250+
html = html.replace('///PCBDATA///', get_compressed_pcbdata(pcbdata))
242251
html = html.replace('///UTILJS///', get_file_content('util.js'))
243252
html = html.replace('///RENDERJS///', get_file_content('render.js'))
244253
html = html.replace('///IBOMJS///', get_file_content('ibom.js'))
Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
"""
2+
Copyright 2014 Eduard Tomasek
3+
This work is free. You can redistribute it and/or modify it under the
4+
terms of the Do What The Fuck You Want To Public License, Version 2,
5+
as published by Sam Hocevar. See the COPYING file for more details.
6+
"""
7+
import sys
8+
if sys.version_info[0] == 3:
9+
unichr = chr
10+
11+
12+
class LZString:
13+
14+
def __init__(self):
15+
pass
16+
17+
@staticmethod
18+
def compress(uncompressed):
19+
20+
if uncompressed is None:
21+
return ''
22+
23+
context_dictionary = {}
24+
context_dictionary_to_create = {}
25+
context_w = ''
26+
context_enlarge_in = 2
27+
28+
context_dict_size = 3
29+
context_num_bits = 2
30+
context_data_string = ''
31+
context_data_val = 0
32+
context_data_position = 0
33+
34+
uncompressed = uncompressed
35+
36+
for ii in range(len(uncompressed)):
37+
context_c = uncompressed[ii]
38+
39+
if context_c not in context_dictionary:
40+
context_dictionary[context_c] = context_dict_size
41+
context_dict_size += 1
42+
context_dictionary_to_create[context_c] = True
43+
44+
context_wc = context_w + context_c
45+
46+
if context_wc in context_dictionary:
47+
context_w = context_wc
48+
else:
49+
if context_w in context_dictionary_to_create:
50+
if ord(context_w[0]) < 256:
51+
for _ in range(context_num_bits):
52+
context_data_val = (context_data_val << 1)
53+
54+
if context_data_position == 15:
55+
context_data_position = 0
56+
context_data_string += unichr(context_data_val)
57+
context_data_val = 0
58+
else:
59+
context_data_position += 1
60+
61+
value = ord(context_w[0])
62+
63+
for i in range(8):
64+
context_data_val = (
65+
(context_data_val << 1) | (value & 1)
66+
)
67+
68+
if context_data_position == 15:
69+
context_data_position = 0
70+
context_data_string += unichr(context_data_val)
71+
context_data_val = 0
72+
else:
73+
context_data_position += 1
74+
75+
value = value >> 1
76+
else:
77+
value = 1
78+
79+
for i in range(context_num_bits):
80+
context_data_val = (context_data_val << 1) | value
81+
82+
if context_data_position == 15:
83+
context_data_position = 0
84+
context_data_string += unichr(context_data_val)
85+
context_data_val = 0
86+
else:
87+
context_data_position += 1
88+
89+
value = 0
90+
91+
value = ord(context_w[0])
92+
93+
for i in range(16):
94+
context_data_val = (
95+
(context_data_val << 1) | (value & 1)
96+
)
97+
98+
if context_data_position == 15:
99+
context_data_position = 0
100+
context_data_string += unichr(context_data_val)
101+
context_data_val = 0
102+
else:
103+
context_data_position += 1
104+
105+
value = value >> 1
106+
107+
context_enlarge_in -= 1
108+
109+
if context_enlarge_in == 0:
110+
context_enlarge_in = pow(2, context_num_bits)
111+
context_num_bits += 1
112+
113+
context_dictionary_to_create.pop(context_w, None)
114+
# del context_dictionary_to_create[context_w]
115+
else:
116+
value = context_dictionary[context_w]
117+
118+
for i in range(context_num_bits):
119+
context_data_val = (
120+
(context_data_val << 1) | (value & 1)
121+
)
122+
123+
if context_data_position == 15:
124+
context_data_position = 0
125+
context_data_string += unichr(context_data_val)
126+
context_data_val = 0
127+
else:
128+
context_data_position += 1
129+
130+
value = value >> 1
131+
132+
context_enlarge_in -= 1
133+
134+
if context_enlarge_in == 0:
135+
context_enlarge_in = pow(2, context_num_bits)
136+
context_num_bits += 1
137+
138+
context_dictionary[context_wc] = context_dict_size
139+
context_dict_size += 1
140+
context_w = context_c
141+
if context_w != '':
142+
if context_w in context_dictionary_to_create:
143+
if ord(context_w[0]) < 256:
144+
for i in range(context_num_bits):
145+
context_data_val = (context_data_val << 1)
146+
147+
if context_data_position == 15:
148+
context_data_position = 0
149+
context_data_string += unichr(context_data_val)
150+
context_data_val = 0
151+
else:
152+
context_data_position += 1
153+
154+
value = ord(context_w[0])
155+
156+
for i in range(8):
157+
context_data_val = (
158+
(context_data_val << 1) | (value & 1)
159+
)
160+
161+
if context_data_position == 15:
162+
context_data_position = 0
163+
context_data_string += unichr(context_data_val)
164+
context_data_val = 0
165+
else:
166+
context_data_position += 1
167+
168+
value = value >> 1
169+
else:
170+
value = 1
171+
172+
for i in range(context_num_bits):
173+
context_data_val = (context_data_val << 1) | value
174+
175+
if context_data_position == 15:
176+
context_data_position = 0
177+
context_data_string += unichr(context_data_val)
178+
context_data_val = 0
179+
else:
180+
context_data_position += 1
181+
182+
value = 0
183+
184+
value = ord(context_w[0])
185+
186+
for i in range(16):
187+
context_data_val = (
188+
(context_data_val << 1) | (value & 1)
189+
)
190+
191+
if context_data_position == 15:
192+
context_data_position = 0
193+
context_data_string += unichr(context_data_val)
194+
context_data_val = 0
195+
else:
196+
context_data_position += 1
197+
198+
value = value >> 1
199+
200+
context_enlarge_in -= 1
201+
202+
if context_enlarge_in == 0:
203+
context_enlarge_in = pow(2, context_num_bits)
204+
context_num_bits += 1
205+
206+
context_dictionary_to_create.pop(context_w, None)
207+
# del context_dictionary_to_create[context_w]
208+
else:
209+
value = context_dictionary[context_w]
210+
211+
for i in range(context_num_bits):
212+
context_data_val = (context_data_val << 1) | (value & 1)
213+
214+
if context_data_position == 15:
215+
context_data_position = 0
216+
context_data_string += unichr(context_data_val)
217+
context_data_val = 0
218+
else:
219+
context_data_position += 1
220+
221+
value = value >> 1
222+
223+
context_enlarge_in -= 1
224+
225+
if context_enlarge_in == 0:
226+
context_num_bits += 1
227+
228+
value = 2
229+
230+
for i in range(context_num_bits):
231+
context_data_val = (context_data_val << 1) | (value & 1)
232+
233+
if context_data_position == 15:
234+
context_data_position = 0
235+
context_data_string += unichr(context_data_val)
236+
context_data_val = 0
237+
else:
238+
context_data_position += 1
239+
240+
value = value >> 1
241+
242+
context_data_val = (context_data_val << 1)
243+
while context_data_position != 15:
244+
context_data_position += 1
245+
context_data_val = (context_data_val << 1)
246+
context_data_string += unichr(context_data_val)
247+
248+
return context_data_string
249+
250+
@staticmethod
251+
def compress_to_utf16(string):
252+
253+
if string is None:
254+
return ''
255+
256+
output = ''
257+
current = 0
258+
status = 0
259+
260+
string = LZString.compress(string)
261+
262+
for i in range(len(string)):
263+
c = ord(string[i])
264+
265+
if status == 0:
266+
status += 1
267+
output += unichr(((c >> 1) + 32))
268+
current = (c & 1) << 14
269+
elif status == 1:
270+
status += 1
271+
output += unichr(((current + (c >> 2)) + 32))
272+
current = (c & 3) << 13
273+
elif status == 2:
274+
status += 1
275+
output += unichr(((current + (c >> 3)) + 32))
276+
current = (c & 7) << 12
277+
elif status == 3:
278+
status += 1
279+
output += unichr(((current + (c >> 4)) + 32))
280+
current = (c & 15) << 11
281+
elif status == 4:
282+
status += 1
283+
output += unichr(((current + (c >> 5)) + 32))
284+
current = (c & 31) << 10
285+
elif status == 5:
286+
status += 1
287+
output += unichr(((current + (c >> 6)) + 32))
288+
current = (c & 63) << 9
289+
elif status == 6:
290+
status += 1
291+
output += unichr(((current + (c >> 7)) + 32))
292+
current = (c & 127) << 8
293+
elif status == 7:
294+
status += 1
295+
output += unichr(((current + (c >> 8)) + 32))
296+
current = (c & 255) << 7
297+
elif status == 8:
298+
status += 1
299+
output += unichr(((current + (c >> 9)) + 32))
300+
current = (c & 511) << 6
301+
elif status == 9:
302+
status += 1
303+
output += unichr(((current + (c >> 10)) + 32))
304+
current = (c & 1023) << 5
305+
elif status == 10:
306+
status += 1
307+
output += unichr(((current + (c >> 11)) + 32))
308+
current = (c & 2047) << 4
309+
elif status == 11:
310+
status += 1
311+
output += unichr(((current + (c >> 12)) + 32))
312+
current = (c & 4095) << 3
313+
elif status == 12:
314+
status += 1
315+
output += unichr(((current + (c >> 13)) + 32))
316+
current = (c & 8191) << 2
317+
elif status == 13:
318+
status += 1
319+
output += unichr(((current + (c >> 14)) + 32))
320+
current = (c & 16383) << 1
321+
elif status == 14:
322+
status += 1
323+
output += unichr(((current + (c >> 15)) + 32))
324+
output += unichr((c & 32767) + 32)
325+
326+
status = 0
327+
328+
output += unichr(current + 32)
329+
330+
return output

InteractiveHtmlBom/web/ibom.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
///SPLITJS///
1414
///////////////////////////////////////////////
1515

16+
///////////////////////////////////////////////
17+
///LZ-STRING///
18+
///////////////////////////////////////////////
19+
1620
///////////////////////////////////////////////
1721
///POINTER_EVENTS_POLYFILL///
1822
///////////////////////////////////////////////

0 commit comments

Comments
 (0)