resedit 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+
3
+ module Resedit
4
+
5
+ class KeyboardRuConvertTable < ConvertTable
6
+
7
+ def initialize()
8
+ super()
9
+ @table={
10
+ 'Q' => 'Й',
11
+ 'W' => 'Ц',
12
+ 'E' => 'У',
13
+ 'R' => 'К',
14
+ 'T' => 'Е',
15
+ 'Y' => 'Н',
16
+ 'U' => 'Г',
17
+ 'I' => 'Ш',
18
+ 'O' => 'Щ',
19
+ 'P' => 'З',
20
+ '{' => 'Х',
21
+ '}' => 'Ъ',
22
+ 'A' => 'Ф',
23
+ 'S' => 'Ы',
24
+ 'D' => 'В',
25
+ 'F' => 'А',
26
+ 'G' => 'П',
27
+ 'H' => 'Р',
28
+ 'J' => 'О',
29
+ 'K' => 'Л',
30
+ 'L' => 'Д',
31
+ ':' => 'Ж',
32
+ "\"" => 'Э',
33
+ 'Z' => 'Я',
34
+ 'X' => 'Ч',
35
+ 'C' => 'С',
36
+ 'V' => 'М',
37
+ 'B' => 'И',
38
+ 'N' => 'Т',
39
+ 'M' => 'Ь',
40
+ '<' => 'Б',
41
+ '>' => 'Ю',
42
+
43
+ 'q' => 'й',
44
+ 'w' => 'ц',
45
+ 'e' => 'у',
46
+ 'r' => 'к',
47
+ 't' => 'е',
48
+ 'y' => 'н',
49
+ 'u' => 'г',
50
+ 'i' => 'ш',
51
+ 'o' => 'щ',
52
+ 'p' => 'з',
53
+ '[' => 'х',
54
+ ']' => 'ъ',
55
+ 'a' => 'ф',
56
+ 's' => 'ы',
57
+ 'd' => 'в',
58
+ 'f' => 'а',
59
+ 'g' => 'п',
60
+ 'h' => 'р',
61
+ 'j' => 'о',
62
+ 'k' => 'л',
63
+ 'l' => 'д',
64
+ ';' => 'ж',
65
+ "\'" => 'э',
66
+ 'z' => 'я',
67
+ 'x' => 'ч',
68
+ 'c' => 'с',
69
+ 'v' => 'м',
70
+ 'b' => 'и',
71
+ 'n' => 'т',
72
+ 'm' => 'ь',
73
+ ',' => 'б',
74
+ '.' => 'ю',
75
+
76
+ '~' => 'Ё',
77
+ '`' => 'ё'
78
+ }
79
+ end
80
+
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,10 @@
1
+ module Resedit
2
+
3
+ class ConvertTable
4
+
5
+ def initialize()
6
+ end
7
+
8
+ end
9
+
10
+ end
@@ -0,0 +1,117 @@
1
+ module Resedit
2
+
3
+ class TextEscaper
4
+
5
+ STD_TABLE = {0x5C=>"\\\\", 0x0A=>"\\n", 0x0D=>"\\r", 0x09=>"\\t", 0x07=>"\\a", 0x08=>"\\b", 0x0C=>"\\f", 0x0B=>"\\v", 0x1B=>"\\e"}
6
+
7
+ def escape(line)
8
+ out=""
9
+ line.each_byte {|b|
10
+ out += _escape(b)
11
+ }
12
+ return out
13
+ end
14
+
15
+ def unescape(line); end
16
+
17
+ protected
18
+
19
+ def tableReplace(str,tbl,numproc=true)
20
+ ntbl={}
21
+ if tbl
22
+ tbl.each{|b,v|
23
+ ntbl[v[0]]={} if !ntbl[v[0]]
24
+ ntbl[v[0]][v]=b
25
+ }
26
+ end
27
+ pos=0
28
+ res=""
29
+ while pos < str.length
30
+ val=str[pos]
31
+ inc=1
32
+ if ntbl[val]
33
+ ntbl[val].each{|v,b|
34
+ next if str.length < pos+v.length+1
35
+ if v==str[pos,v.length]
36
+ val=b.chr
37
+ inc=v.length
38
+ break
39
+ end
40
+ }
41
+ end
42
+ if inc==1 && numproc && val=="\\"
43
+ raise "Bad escape sequence: "+str if str.length < pos+5
44
+ num = str[pos+1,3]
45
+ byte = num[0].upcase=="X" ? num[1,2].to_i(16) : num.to_i
46
+ raise "Bad numeric escape "+num+": "+str if (byte==0 and num!="000" and num!="x00") || byte>255 || byte<0
47
+ val=byte.chr
48
+ inc=4
49
+ end
50
+ res += val
51
+ pos += inc
52
+ end
53
+ return res
54
+ end
55
+
56
+ def _escape(b); end
57
+ end
58
+
59
+
60
+ class SlashEscaper < TextEscaper
61
+
62
+ def _escape(b)
63
+ return '\\\\' if b==0x5c
64
+ b<0x20 ? sprintf("\\x%02X", b) : b.chr
65
+ end
66
+
67
+ def unescape(line)
68
+ tableReplace(line,{0x5C=>"\\\\"})
69
+ end
70
+
71
+ end
72
+
73
+
74
+ class StdEscaper < SlashEscaper
75
+
76
+ def _escape(b)
77
+ STD_TABLE[b] ? STD_TABLE[b] : super(b)
78
+ end
79
+
80
+ def unescape(line)
81
+ tableReplace(line,STD_TABLE)
82
+ end
83
+
84
+ end
85
+
86
+
87
+ class TableEscaper < TextEscaper
88
+
89
+ def initialize(table=nil, stdTable=STD_TABLE)
90
+ @table={}
91
+ if stdTable
92
+ stdTable.each {|b, e|
93
+ add(b, e)
94
+ }
95
+ end
96
+ if table
97
+ table.each {|b, e|
98
+ add(b,e)
99
+ }
100
+ end
101
+ end
102
+
103
+ def add(byte, esc)
104
+ @table[byte] = esc
105
+ end
106
+
107
+ def _escape(b)
108
+ @table[b] ? @table[b] : b.chr
109
+ end
110
+
111
+ def unescape(line)
112
+ tableReplace(line,@table,false)
113
+ end
114
+
115
+ end
116
+
117
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module Resedit
3
+
4
+ class TextFormat
5
+
6
+ def initialize(encoding)
7
+ @encoding=encoding
8
+ end
9
+
10
+ def saveLines(fname, lines, meta); end
11
+
12
+ def loadLines(fname); end
13
+
14
+ end
15
+
16
+ class FormatTxt < TextFormat
17
+
18
+ def initialize(encoding)
19
+ super((encoding or 'cp1251'))
20
+ end
21
+
22
+ def saveLines(fname, lines, meta)
23
+ open(fname+".txt", "w:"+@encoding) {|f|
24
+ lines.each {|l|
25
+ l.force_encoding('utf-8')
26
+ f.write(l)
27
+ f.write("\r\n")
28
+ }
29
+ }
30
+ end
31
+
32
+ def loadLines(fname)
33
+ lns=[]
34
+ open(fname+".txt", "r:"+@encoding+":utf-8").each_line {|line|
35
+ lns += [line.chomp]
36
+ }
37
+ lns=lns[0..-2] if lns.last == ""
38
+ return lns
39
+ end
40
+
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,46 @@
1
+ require 'resedit/text/format_text'
2
+ require 'builder'
3
+ require 'rexml/document'
4
+
5
+ module Resedit
6
+
7
+ class FormatXml < TextFormat
8
+
9
+ def initialize(encoding)
10
+ super('utf-8')
11
+ end
12
+
13
+ def saveLines(fname, lines, meta)
14
+ open(fname+".xml", "w:"+@encoding) {|f|
15
+ xml=Builder::XmlMarkup.new(:indent => 2 , :target=>f)
16
+ xml.instruct! :xml, :encoding => @encoding
17
+ xml.body {|b|
18
+ lines.each.with_index{|l,i|
19
+ mt = {'id' => i}
20
+ mt.update(meta[i]) if meta[i]
21
+ b.text(l, mt)
22
+ }
23
+ }
24
+ }
25
+ end
26
+
27
+ def loadLines(fname)
28
+ hs={}
29
+ open(fname+".xml", "r:"+@encoding) {|f|
30
+ doc=REXML::Document.new(f)
31
+ doc.elements.each("body/text"){|e|
32
+ hs[e.attributes['id']] = e.text
33
+ }
34
+ }
35
+ raise "No data in xml" if !hs.length
36
+ lns=[]
37
+ for i in 0..hs.length-1
38
+ raise "Text not found: "+i if !hs[i]
39
+ lns+=[ hs[i] ]
40
+ end
41
+ return lns
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,190 @@
1
+ require 'resedit/app/app'
2
+ module Resedit
3
+
4
+ class Huffman
5
+
6
+ class Node
7
+ attr_accessor :value, :parent, :left, :right
8
+
9
+ def initialize(value=nil, parent=nil)
10
+ @value=value
11
+ end
12
+
13
+ def addNode(isLeft,value=nil)
14
+ n=Node.new(value)
15
+ if isLeft
16
+ @left=n
17
+ else
18
+ @right=n
19
+ end
20
+ return n
21
+ end
22
+
23
+ def addLeft(value=nil)
24
+ addNode(true, value)
25
+ end
26
+
27
+ def addRight(value=nil)
28
+ addNode(false, value)
29
+ end
30
+
31
+ def getLeafs(leftS,rightS,path='')
32
+ return {path=>@value} if @value
33
+ l=@left.getLeafs(leftS, rightS, path+leftS)
34
+ r=@right.getLeafs(leftS, rightS, path+rightS)
35
+ return l.merge(r)
36
+ end
37
+
38
+ end
39
+
40
+
41
+ class Balancer
42
+ attr_reader :huff
43
+ def initialize(huff)
44
+ @huff = huff
45
+ @tbl = {}
46
+ end
47
+
48
+ def addData(bytes)
49
+ bytes.each_byte{|b|
50
+ @tbl[b] = 0 if !@tbl[b]
51
+ @tbl[b] += 1
52
+ }
53
+ end
54
+
55
+ def balanceValues()
56
+ end
57
+
58
+ def balanceTree()
59
+ raise "Not implemented."
60
+ end
61
+ end
62
+
63
+
64
+ attr_reader :tree
65
+
66
+ def initialize(zeroLeft, reverseBitsInByte=false)
67
+ @tree=Huffman::Node.new()
68
+ @zeroLeft, @reverseBits = zeroLeft,reverseBitsInByte
69
+ end
70
+
71
+ def decodeTable(recalc=false)
72
+ if @recalc || !@decodeTbl
73
+ tbl = @tree.getLeafs(@zeroLeft ? '0' : '1', @zeroLeft ? '1' : '0')
74
+ @decodeTbl = {}
75
+ tbl.each{|k,v|
76
+ @decodeTbl[k.length] = {} if !@decodeTbl[k.length]
77
+ @decodeTbl[k.length][k.to_i(2)] = v
78
+ }
79
+ end
80
+ return @decodeTbl
81
+ end
82
+
83
+ def encodeTable(recalc=false)
84
+ if @recalc || !@encodeTbl
85
+ tbl = @tree.getLeafs(@zeroLeft ? '0' : '1', @zeroLeft ? '1' : '0')
86
+ @encodeTbl = {}
87
+ tbl.each{|k,v|
88
+ @encodeTbl[v] = [k.reverse.to_i(2), k.length]
89
+ }
90
+ end
91
+ return @encodeTbl
92
+ end
93
+
94
+
95
+ def balancer()
96
+ return Huffman::Balancer.new(self)
97
+ end
98
+
99
+ def debug()
100
+ tbl=decodeTable()
101
+ info="---huffman table---\n"
102
+ bts={}
103
+ tbl.keys.sort.each{|sz|
104
+ tbl[sz].each{|k,v|
105
+ fmt = "0x%02X\t%2d\t%0" + sz.to_s + "b\n"
106
+ info += sprintf(fmt,v,sz,k)
107
+ if not bts[v]
108
+ bts[v] = 1
109
+ else
110
+ bts[v] += 1
111
+ end
112
+ }
113
+ }
114
+ info += sprintf("---%d bytes---\n",bts.length)
115
+ for i in 0..255
116
+ if !bts[i]
117
+ info+=sprintf("0x%02X - ABSENT\n", i)
118
+ else
119
+ info+=sprintf("0x%02X - %d times\n", i, bts[i]) if bts[i]!=1
120
+ end
121
+ end
122
+ App.get().logd(info)
123
+ end
124
+
125
+ def revbyte(byte)
126
+ return byte if !@reverseBits
127
+ return sprintf("%08b", byte).reverse.to_i(2)
128
+ end
129
+
130
+ def decode(bitstream, endl=0)
131
+ res = ''
132
+ tbl = decodeTable()
133
+ max = tbl.keys.max
134
+ pos = 0
135
+ byte = bitstream[pos].ord
136
+ bytelen = 8
137
+ buf = 0
138
+ buflen = 0
139
+ while true
140
+ buf <<= 1
141
+ buflen += 1
142
+ raise "Huffman decode length overflow" if buflen>max
143
+ buf |= byte & 1
144
+ byte >>= 1
145
+ bytelen -= 1
146
+ if tbl[buflen] && tbl[buflen][buf]
147
+ return res if tbl[buflen][buf] == endl
148
+ res += tbl[buflen][buf].chr
149
+ buf = 0
150
+ buflen = 0
151
+ end
152
+
153
+ next if bytelen>0
154
+ pos += 1
155
+ break if pos >= bitstream.length
156
+ bytelen = 8
157
+ byte = revbyte(bitstream[pos].ord)
158
+ end
159
+ return res
160
+ end
161
+
162
+ def encode(bytes, endl=0)
163
+ if endl != nil && bytes[-1] != endl
164
+ bytes += endl.chr
165
+ end
166
+ res = ''
167
+ tbl = encodeTable()
168
+ byte = 0
169
+ bytelen = 0
170
+ bytes.each_byte{|b|
171
+ raise sprintf("No byte in encode table: %02X", b) if !tbl[b]
172
+ val = tbl[b][0]
173
+ for i in 0..tbl[b][1]-1
174
+ byte |= ((val & 1) << bytelen)
175
+ val >>= 1
176
+ bytelen += 1
177
+ if bytelen == 8
178
+ res += revbyte(byte).chr
179
+ bytelen = 0
180
+ byte = 0
181
+ end
182
+ end
183
+ }
184
+ res += revbyte(byte).chr if bytelen > 0
185
+ return res
186
+ end
187
+
188
+ end
189
+
190
+ end