nwn-lib 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -3
- data/SETTINGS.rdoc +2 -1
- data/bin/nwn-gff +1 -7
- data/lib/nwn/gff.rb +1 -1
- data/lib/nwn/gff/field.rb +0 -54
- data/lib/nwn/gff/reader.rb +13 -7
- data/lib/nwn/gff/struct.rb +0 -40
- data/lib/nwn/gff/writer.rb +6 -3
- data/lib/nwn/json_support.rb +83 -3
- data/lib/nwn/settings.rb +2 -3
- data/lib/nwn/version.rb +1 -1
- data/lib/nwn/xml_support.rb +0 -10
- data/lib/nwn/yaml_support.rb +10 -1
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -42,10 +42,9 @@ With the release of 0.4.0, the API changed significantly. Previous yaml dumps ma
|
|
42
42
|
I can't help you with your API bindings, but for your YAML dumps, a converter script has been provided (see {file:BINARIES}).
|
43
43
|
|
44
44
|
|
45
|
-
===
|
45
|
+
=== Upgrade from 0.4.x to 0.5.x
|
46
46
|
|
47
|
-
|
48
|
-
This will be worked around in a future release until the release of ruby 1.9, which will provide native charset support.
|
47
|
+
All with version 0.4.x produced files should be compatible with 0.5.0. Your application might require some porting to ruby 1.9.
|
49
48
|
|
50
49
|
|
51
50
|
=== Quickstart
|
data/SETTINGS.rdoc
CHANGED
@@ -8,7 +8,8 @@ Under linux, just add them to your shell environment (usually .bashrc), like so:
|
|
8
8
|
|
9
9
|
== NWN_LIB_IN_ENCODING
|
10
10
|
|
11
|
-
The character encoding your local data files are in. Defaults to ISO-8859-1.
|
11
|
+
The character encoding your local data (gff) files are in. Defaults to ISO-8859-1.
|
12
|
+
Extended dump formats like yaml, xml are always format-specific, usually UTF-8.
|
12
13
|
|
13
14
|
== NWN_LIB_PRETTY_JSON
|
14
15
|
|
data/bin/nwn-gff
CHANGED
@@ -8,7 +8,6 @@ Thread.abort_on_exception = true
|
|
8
8
|
$options = {
|
9
9
|
:backup => nil,
|
10
10
|
:encoding => nil,
|
11
|
-
:out_encoding => nil,
|
12
11
|
:force => false,
|
13
12
|
:infile => '-',
|
14
13
|
:outfile => '-',
|
@@ -50,14 +49,10 @@ begin OptionParser.new do |o|
|
|
50
49
|
"(see `man cp' for a description)" do |b|
|
51
50
|
$options[:backup] = b.nil? ? true : b
|
52
51
|
end
|
53
|
-
o.on "--encoding ENCODING", "sets the used
|
52
|
+
o.on "--encoding ENCODING", "sets the used encoding in which your gff",
|
54
53
|
"files are encoded in" do |e|
|
55
54
|
$options[:encoding] = e
|
56
55
|
end
|
57
|
-
o.on "--out-encoding ENCODING", "sets the used output encoding",
|
58
|
-
"(defaults to UTF-8)" do |e|
|
59
|
-
$options[:out_encoding] = e
|
60
|
-
end
|
61
56
|
|
62
57
|
o.on "-1", "--nwn1", "Allow 16 byte resrefs." do
|
63
58
|
ENV['NWN_LIB_RESREF32'] = nil
|
@@ -121,7 +116,6 @@ $options[:informat] or fail "No input format specified."
|
|
121
116
|
$options[:outformat] or fail "No output format specified."
|
122
117
|
|
123
118
|
NWN.setting(:in_encoding, $options[:encoding]) if $options[:encoding]
|
124
|
-
NWN.setting(:out_encoding, $options[:out_encoding]) if $options[:out_encoding]
|
125
119
|
|
126
120
|
if :auto == $options[:informat]
|
127
121
|
$options[:informat] = NWN::Gff.guess_file_format($options[:infile].downcase)
|
data/lib/nwn/gff.rb
CHANGED
data/lib/nwn/gff/field.rb
CHANGED
@@ -216,58 +216,4 @@ module NWN::Gff::Field
|
|
216
216
|
end
|
217
217
|
end
|
218
218
|
#:startdoc:
|
219
|
-
|
220
|
-
# Deep-unboxes a Hash, e.g. iterating down, converting all strings
|
221
|
-
# from the native charset.
|
222
|
-
def self.unbox! element, parent_label, parent
|
223
|
-
element.extend(NWN::Gff::Field)
|
224
|
-
element.field_label = parent_label
|
225
|
-
element.parent = parent
|
226
|
-
element.str_ref ||= NWN::Gff::Field::DEFAULT_STR_REF if element.respond_to?('str_ref=')
|
227
|
-
|
228
|
-
element.extend_meta_classes
|
229
|
-
case element.field_type
|
230
|
-
when :cexolocstr
|
231
|
-
mod = {}
|
232
|
-
element.field_value.each {|x,y|
|
233
|
-
mod[x] = NWN.iconv_native_to_gff(y)
|
234
|
-
}
|
235
|
-
mod.each {|x,y|
|
236
|
-
element.field_value.delete(x)
|
237
|
-
element.field_value[x.to_i] = y
|
238
|
-
}
|
239
|
-
when :cexostr
|
240
|
-
element.field_value = NWN.iconv_native_to_gff(element.field_value)
|
241
|
-
|
242
|
-
when :list
|
243
|
-
mod = {}
|
244
|
-
element.field_value.each_with_index {|x,idx|
|
245
|
-
mod[idx] = NWN::Gff::Struct.unbox!(x, element)
|
246
|
-
}
|
247
|
-
mod.each {|x,y|
|
248
|
-
element.field_value[x] = y
|
249
|
-
}
|
250
|
-
when :struct
|
251
|
-
element.field_value = NWN::Gff::Struct.unbox!(element.field_value, element)
|
252
|
-
end
|
253
|
-
element.validate
|
254
|
-
element
|
255
|
-
end
|
256
|
-
|
257
|
-
# Returns a hash of this Field without the API calls mixed in,
|
258
|
-
# all language-strings transformed by str_handler.
|
259
|
-
def box
|
260
|
-
t = Hash[self]
|
261
|
-
t.delete('label')
|
262
|
-
case field_type
|
263
|
-
when :cexolocstr
|
264
|
-
t['value'].each {|x,y|
|
265
|
-
t['value'][x] = NWN.iconv_gff_to_native(y)
|
266
|
-
}
|
267
|
-
when :cexostr
|
268
|
-
t['value'] = NWN.iconv_gff_to_native(t['value'])
|
269
|
-
end
|
270
|
-
t
|
271
|
-
end
|
272
|
-
|
273
219
|
end
|
data/lib/nwn/gff/reader.rb
CHANGED
@@ -14,6 +14,7 @@ class NWN::Gff::Reader
|
|
14
14
|
|
15
15
|
def initialize io #:nodoc:
|
16
16
|
@io = io
|
17
|
+
io.internal_encoding == nil or raise "passed io needs to be binary, is #{io.internal_encoding.inspect}"
|
17
18
|
read_all
|
18
19
|
end
|
19
20
|
|
@@ -47,7 +48,7 @@ class NWN::Gff::Reader
|
|
47
48
|
@io.seek(label_offset)
|
48
49
|
@labels = @io.e_read(label_len, "labels")
|
49
50
|
@labels = @labels.unpack("A16" * label_count)
|
50
|
-
@labels.map! {|l| l.
|
51
|
+
@labels.map! {|l| l.force_encoding("ASCII") }
|
51
52
|
|
52
53
|
@io.seek(field_data_offset)
|
53
54
|
@field_data = @io.e_read(field_data_count, "field_data")
|
@@ -75,8 +76,8 @@ class NWN::Gff::Reader
|
|
75
76
|
raise GffError, "struct index #{index} outside of struct_array" if
|
76
77
|
index * 3 + 3 > @structs.size + 1
|
77
78
|
|
78
|
-
file_type = file_type.
|
79
|
-
file_version = file_version.
|
79
|
+
file_type = file_type.force_encoding('ASCII') if file_type
|
80
|
+
file_version = file_version.force_encoding('ASCII') if file_version
|
80
81
|
|
81
82
|
struct.struct_id = type
|
82
83
|
struct.data_type = file_type
|
@@ -159,11 +160,15 @@ class NWN::Gff::Reader
|
|
159
160
|
|
160
161
|
when :cexostr
|
161
162
|
len = @field_data[data_or_offset, 4].unpack("V")[0]
|
162
|
-
@field_data[data_or_offset + 4, len].
|
163
|
+
str = @field_data[data_or_offset + 4, len].force_encoding(NWN.setting :in_encoding)
|
164
|
+
str.valid_encoding? or raise "Invalid encoding bytes in cexostr: #{str.inspect}"
|
165
|
+
str
|
163
166
|
|
164
167
|
when :resref
|
165
168
|
len = @field_data[data_or_offset, 1].unpack("C")[0]
|
166
|
-
@field_data[data_or_offset + 1, len].
|
169
|
+
str = @field_data[data_or_offset + 1, len].force_encoding(NWN.setting :in_encoding)
|
170
|
+
str.valid_encoding? or raise "Invalid encoding bytes in resref: #{str.inspect}"
|
171
|
+
str
|
167
172
|
|
168
173
|
when :cexolocstr
|
169
174
|
exostr = {}
|
@@ -176,7 +181,8 @@ class NWN::Gff::Reader
|
|
176
181
|
|
177
182
|
str_count.times {
|
178
183
|
id, len = all.unpack("VV")
|
179
|
-
str = all[8, len].unpack("a*")[0].
|
184
|
+
str = all[8, len].unpack("a*")[0].force_encoding(NWN.setting :in_encoding)
|
185
|
+
str.valid_encoding? or raise "Invalid encoding bytes in cexolocstr: #{str.inspect}"
|
180
186
|
all = all[(8 + len)..-1]
|
181
187
|
exostr[id] = str
|
182
188
|
}
|
@@ -185,7 +191,7 @@ class NWN::Gff::Reader
|
|
185
191
|
|
186
192
|
when :void
|
187
193
|
len = @field_data[data_or_offset, 4].unpack("V")[0]
|
188
|
-
@field_data[data_or_offset + 4, len].unpack("a*")[0]
|
194
|
+
@field_data[data_or_offset + 4, len].unpack("a*")[0].force_encoding("BINARY")
|
189
195
|
|
190
196
|
when :struct
|
191
197
|
read_struct data_or_offset, nil, field.parent.data_version
|
data/lib/nwn/gff/struct.rb
CHANGED
@@ -222,44 +222,4 @@ module NWN::Gff::Struct
|
|
222
222
|
def / path
|
223
223
|
by_path(path)
|
224
224
|
end
|
225
|
-
|
226
|
-
# Deep-unboxes a Hash, e.g. iterating down, converting it to
|
227
|
-
# the native charset.
|
228
|
-
def self.unbox! o, parent = nil
|
229
|
-
o.extend(NWN::Gff::Struct)
|
230
|
-
o.element = parent if parent
|
231
|
-
o.struct_id = o.delete('__struct_id')
|
232
|
-
o.data_type = o.delete('__data_type')
|
233
|
-
o.data_version = o.delete('__data_version')
|
234
|
-
o.data_version ||= NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
235
|
-
|
236
|
-
NWN.log_debug("Unboxed without a root data type") if
|
237
|
-
!parent && !o.data_type
|
238
|
-
NWN.log_debug("Unboxed with explicit data type #{o.data_type.inspect}") if
|
239
|
-
parent && o.data_type
|
240
|
-
|
241
|
-
o.each {|label,element|
|
242
|
-
o[label] = NWN::Gff::Field.unbox!(element, label, o)
|
243
|
-
}
|
244
|
-
|
245
|
-
o
|
246
|
-
end
|
247
|
-
|
248
|
-
# Returns a hash of this Struct without the API calls mixed in,
|
249
|
-
# converting it from the native charset.
|
250
|
-
def box
|
251
|
-
t = Hash[self]
|
252
|
-
t.merge!({
|
253
|
-
'__struct_id' => self.struct_id
|
254
|
-
})
|
255
|
-
t.merge!({
|
256
|
-
'__data_version' => self.data_version,
|
257
|
-
}) if self.data_version && self.data_version !=
|
258
|
-
NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
259
|
-
t.merge!({
|
260
|
-
'__data_type' => self.data_type
|
261
|
-
}) if @data_type
|
262
|
-
t
|
263
|
-
end
|
264
|
-
|
265
225
|
end
|
data/lib/nwn/gff/writer.rb
CHANGED
@@ -160,11 +160,13 @@ private
|
|
160
160
|
|
161
161
|
when :resref
|
162
162
|
fields_of_this_struct << add_data_field(v.field_type, k, @field_data.size)
|
163
|
-
|
163
|
+
fv = v.field_value.encode(NWN.setting :in_encoding)
|
164
|
+
@field_data << [fv.size, fv].pack("Ca*")
|
164
165
|
|
165
166
|
when :cexostr
|
166
167
|
fields_of_this_struct << add_data_field(v.field_type, k, @field_data.size)
|
167
|
-
|
168
|
+
fv = v.field_value.encode(NWN.setting :in_encoding)
|
169
|
+
@field_data << [fv.size, fv].pack("Va*")
|
168
170
|
|
169
171
|
when :cexolocstr
|
170
172
|
raise GffError, "type = cexolocstr, but value not a hash (#{v.field_value.class})" unless
|
@@ -184,7 +186,8 @@ private
|
|
184
186
|
].pack("VVV")
|
185
187
|
|
186
188
|
v.field_value.each {|k,v|
|
187
|
-
|
189
|
+
vn = v.encode(NWN.setting :in_encoding)
|
190
|
+
@field_data << [k, vn.size, vn].pack("VVa*")
|
188
191
|
}
|
189
192
|
|
190
193
|
else
|
data/lib/nwn/json_support.rb
CHANGED
@@ -1,18 +1,98 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'base64'
|
2
3
|
|
3
4
|
module NWN::Gff::Struct
|
5
|
+
def json_box
|
6
|
+
t = Hash[self]
|
7
|
+
t.merge!({
|
8
|
+
'__struct_id' => self.struct_id
|
9
|
+
})
|
10
|
+
t.merge!({
|
11
|
+
'__data_version' => self.data_version,
|
12
|
+
}) if self.data_version && self.data_version !=
|
13
|
+
NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
14
|
+
t.merge!({
|
15
|
+
'__data_type' => self.data_type
|
16
|
+
}) if @data_type
|
17
|
+
t
|
18
|
+
end
|
19
|
+
private :json_box
|
20
|
+
|
4
21
|
def to_json(*a)
|
5
|
-
|
22
|
+
json_box.to_json(*a)
|
6
23
|
end
|
7
24
|
end
|
8
25
|
|
9
26
|
module NWN::Gff::Field
|
27
|
+
def json_box
|
28
|
+
t = Hash[self]
|
29
|
+
t.delete('label')
|
30
|
+
case field_type
|
31
|
+
when :void
|
32
|
+
t['value'] = Base64::strict_encode64(t['value'])
|
33
|
+
end
|
34
|
+
t
|
35
|
+
end
|
36
|
+
private :json_box
|
37
|
+
|
10
38
|
def to_json(*a)
|
11
|
-
|
39
|
+
json_box.to_json(*a)
|
12
40
|
end
|
13
41
|
end
|
14
42
|
|
15
43
|
module NWN::Gff::Handler::JSON
|
44
|
+
def self.json_unbox_field element, parent_label, parent
|
45
|
+
element.extend(NWN::Gff::Field)
|
46
|
+
element.field_label = parent_label
|
47
|
+
element.parent = parent
|
48
|
+
element.str_ref ||= NWN::Gff::Field::DEFAULT_STR_REF if element.respond_to?('str_ref=')
|
49
|
+
|
50
|
+
element.extend_meta_classes
|
51
|
+
case element.field_type
|
52
|
+
when :cexolocstr
|
53
|
+
element.field_value.keys.each {|key|
|
54
|
+
val = element.field_value.delete(key)
|
55
|
+
element.field_value[key.to_i] = val
|
56
|
+
}
|
57
|
+
|
58
|
+
when :void
|
59
|
+
element.field_value = Base64::strict_decode64(element.field_value)
|
60
|
+
|
61
|
+
when :list
|
62
|
+
mod = {}
|
63
|
+
element.field_value.each_with_index {|x,idx|
|
64
|
+
mod[idx] = self.json_unbox_struct(x, element)
|
65
|
+
}
|
66
|
+
mod.each {|x,y|
|
67
|
+
element.field_value[x] = y
|
68
|
+
}
|
69
|
+
when :struct
|
70
|
+
element.field_value = self.json_unbox_struct(element.field_value, element)
|
71
|
+
end
|
72
|
+
element.validate
|
73
|
+
element
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.json_unbox_struct o, parent = nil
|
77
|
+
o.extend(NWN::Gff::Struct)
|
78
|
+
o.element = parent if parent
|
79
|
+
o.struct_id = o.delete('__struct_id')
|
80
|
+
o.data_type = o.delete('__data_type')
|
81
|
+
o.data_version = o.delete('__data_version')
|
82
|
+
o.data_version ||= NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
83
|
+
|
84
|
+
NWN.log_debug("Unboxed without a root data type") if
|
85
|
+
!parent && !o.data_type
|
86
|
+
NWN.log_debug("Unboxed with explicit data type #{o.data_type.inspect}") if
|
87
|
+
parent && o.data_type
|
88
|
+
|
89
|
+
o.each {|label,element|
|
90
|
+
o[label] = self.json_unbox_field(element, label, o)
|
91
|
+
}
|
92
|
+
|
93
|
+
o
|
94
|
+
end
|
95
|
+
|
16
96
|
def self.load io
|
17
97
|
json = if io.respond_to?(:to_str)
|
18
98
|
io.to_str
|
@@ -22,7 +102,7 @@ module NWN::Gff::Handler::JSON
|
|
22
102
|
io.read
|
23
103
|
end
|
24
104
|
|
25
|
-
|
105
|
+
self.json_unbox_struct(JSON.parse(json), nil)
|
26
106
|
end
|
27
107
|
|
28
108
|
def self.dump struct, io
|
data/lib/nwn/settings.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module NWN
|
2
2
|
SETTING_DEFAULT_VALUES = {
|
3
|
-
'NWN_LIB_IN_ENCODING' => 'ISO-8859-1'
|
4
|
-
'NWN_LIB_OUT_ENCODING' => 'UTF-8'
|
3
|
+
'NWN_LIB_IN_ENCODING' => 'ISO-8859-1'
|
5
4
|
}
|
6
5
|
|
7
6
|
# This writes a internal warnings and debug messages to stderr.
|
@@ -49,7 +48,7 @@ module NWN
|
|
49
48
|
|
50
49
|
# Converts text from native format (such as json) to Gff (required by NWN).
|
51
50
|
def self.iconv_native_to_gff text
|
52
|
-
text.encode(NWN.setting(:
|
51
|
+
text.encode(NWN.setting(:in_encoding))
|
53
52
|
end
|
54
53
|
|
55
54
|
# Converts text from Gff format to native/external, such as json (usually UTF-8).
|
data/lib/nwn/version.rb
CHANGED
data/lib/nwn/xml_support.rb
CHANGED
@@ -152,10 +152,6 @@ public
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def load io
|
155
|
-
old_encoding = NWN.setting(:out_encoding, 'UTF-8')
|
156
|
-
NWN.log_debug("Ignoring custom out_encoding for xml output, always UTF-8") if
|
157
|
-
old_encoding != 'UTF-8'
|
158
|
-
|
159
155
|
doc = XML::Parser.io(io)
|
160
156
|
root = doc.parse.root
|
161
157
|
ret = case @format
|
@@ -168,15 +164,10 @@ public
|
|
168
164
|
raise ArgumentError, "Unsupported XML format registered: #{@format.inspect}"
|
169
165
|
end
|
170
166
|
|
171
|
-
NWN.setting(:out_encoding, old_encoding)
|
172
167
|
ret
|
173
168
|
end
|
174
169
|
|
175
170
|
def dump data, io
|
176
|
-
old_encoding = NWN.setting(:out_encoding, 'UTF-8')
|
177
|
-
NWN.log_debug("Ignoring custom out_encoding for xml output, always UTF-8") if
|
178
|
-
old_encoding != 'UTF-8'
|
179
|
-
|
180
171
|
doc = XML::Document.new
|
181
172
|
doc.root = case @format
|
182
173
|
when :nxml
|
@@ -193,7 +184,6 @@ public
|
|
193
184
|
t = doc.to_s
|
194
185
|
io.write(t)
|
195
186
|
|
196
|
-
NWN.setting(:out_encoding, old_encoding)
|
197
187
|
t.size
|
198
188
|
end
|
199
189
|
end
|
data/lib/nwn/yaml_support.rb
CHANGED
@@ -81,7 +81,16 @@ module NWN::Gff::Field
|
|
81
81
|
map.style = :inline unless NWN::Gff::Handler::YAML::NonInlineableFields.index(self['type'])
|
82
82
|
map.add('type', self['type'])
|
83
83
|
map.add('str_ref', self['str_ref']) if has_str_ref?
|
84
|
-
map.add('value', self['
|
84
|
+
map.add('value', case self['type']
|
85
|
+
when :resref, :cexostr
|
86
|
+
self['value'].encode('utf-8')
|
87
|
+
when :cexolocstr
|
88
|
+
Hash[self['value'].map {|lang,str|
|
89
|
+
[lang, str.encode('utf-8')]
|
90
|
+
}]
|
91
|
+
else
|
92
|
+
self['value']
|
93
|
+
end)
|
85
94
|
end
|
86
95
|
end
|
87
96
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nwn-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Neverwinter Nights 1/2 file formats ruby library
|
15
15
|
email:
|