nwn-lib 0.4.11 → 0.4.12
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +29 -0
- data/README +2 -0
- data/Rakefile +4 -7
- data/SETTINGS +5 -0
- data/bin/nwn-gff +7 -3
- data/lib/nwn/all.rb +7 -0
- data/lib/nwn/gff.rb +63 -26
- data/lib/nwn/gff/field.rb +6 -6
- data/lib/nwn/gff/reader.rb +0 -3
- data/lib/nwn/gff/struct.rb +9 -6
- data/lib/nwn/json_support.rb +7 -5
- data/lib/nwn/kivinen_support.rb +3 -2
- data/lib/nwn/settings.rb +34 -7
- data/lib/nwn/xml_support.rb +202 -0
- data/lib/nwn/yaml_support.rb +9 -7
- data/spec/gff_spec.rb +22 -13
- data/spec/kivinen_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/struct_data_type_version_spec.rb +82 -0
- metadata +30 -29
- data/spec/data_type_spec.rb +0 -128
data/CHANGELOG
CHANGED
@@ -323,3 +323,32 @@ Bernhard Stoeckner <elven@swordcoast.net> (7):
|
|
323
323
|
A mostly-maintenance release with some API changes. The most invasive changes
|
324
324
|
are some method renames. New are some sane default values for Struct#add_*,
|
325
325
|
and a few more specs. YAML now sets correct .element references.
|
326
|
+
|
327
|
+
=== 0.4.12
|
328
|
+
Bernhard Stoeckner (18):
|
329
|
+
Gff read/write API: documentation, Handler#dump always returns bytes written
|
330
|
+
Settings: iconv: refactor into methods
|
331
|
+
data_type_spec: refactor to be more concise
|
332
|
+
Gff::Struct#data_type=: only emit debug message when new type is non-nil
|
333
|
+
Gff::Handler::JSON: emit terminating newline regardless of :pretty_json
|
334
|
+
JSON: infer data_version like yaml, omit if DEFAULT
|
335
|
+
Gff: error if registering format of same name twice, reverse FileFormatRX hash
|
336
|
+
Gff::Struct: reparenting struct emits debug message only if element != nil
|
337
|
+
Gff::Reader: allow reading of arbitary Gff version files
|
338
|
+
Gff::Struct: data_version allow more freedom in inferring, update spec
|
339
|
+
NWN::Gff: custom xml data format, nwntools.sf.net modpacker read/write support
|
340
|
+
Rakefile: spec output in spec-style format
|
341
|
+
Rakefile: remove obsolete rubyforge target
|
342
|
+
bin/nwn-gff: --out-encoding specified output encoding
|
343
|
+
NWN.setting: return default values for setting new values too
|
344
|
+
spec_helper: set $options to unbreak kivinen spec
|
345
|
+
NWN.log_debug: non-lib frame if available, :debug_trace prints full traces
|
346
|
+
Gff::Field: fix data ranges for int64, dword64
|
347
|
+
0.4.12-rel
|
348
|
+
|
349
|
+
A few new features and some bugfixes this release:
|
350
|
+
- more concise yaml dumps (but backwards-compatible)
|
351
|
+
- some iconv fixes
|
352
|
+
- dword64 and int64 data ranges now correct
|
353
|
+
- support for parsing/dumping modpacker XML
|
354
|
+
- support for parsing/dumping a custom, cleaner XML format
|
data/README
CHANGED
@@ -22,6 +22,8 @@ They should work with NWN2 just as well, since the file format specifications di
|
|
22
22
|
* yaml presentation of data
|
23
23
|
* json presentation of data (with proper UTF-8 conversion)
|
24
24
|
* ruby-native marshalling of gff data
|
25
|
+
* a compact native xml format
|
26
|
+
* nwntools.sf.net-style xml files ("modpacker")
|
25
27
|
|
26
28
|
===== just write, for now:
|
27
29
|
* kivinen-style ("gffprint.pl") presentation of data
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ include FileUtils
|
|
9
9
|
# Configuration
|
10
10
|
##############################################################################
|
11
11
|
NAME = "nwn-lib"
|
12
|
-
VERS = "0.4.
|
12
|
+
VERS = "0.4.12"
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage"]
|
14
14
|
RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
|
15
15
|
'nwn-lib: a ruby library for accessing NWN resource files', \
|
@@ -68,17 +68,12 @@ task :uninstall => [:clean] do
|
|
68
68
|
sh %{sudo gem1.8 uninstall #{NAME}}
|
69
69
|
end
|
70
70
|
|
71
|
-
desc "Upload nwn-lib gem to rubyforge"
|
72
|
-
task :release => [:package] do
|
73
|
-
sh %{rubyforge add_release nwn-lib #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.tgz}
|
74
|
-
sh %{rubyforge add_file nwn-lib #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.gem}
|
75
|
-
end
|
76
|
-
|
77
71
|
require "spec/rake/spectask"
|
78
72
|
|
79
73
|
desc "Run specs with coverage"
|
80
74
|
Spec::Rake::SpecTask.new("spec") do |t|
|
81
75
|
t.spec_files = FileList["spec/*_spec.rb"]
|
76
|
+
t.spec_opts = ["--format s"]
|
82
77
|
t.rcov = true
|
83
78
|
end
|
84
79
|
|
@@ -86,11 +81,13 @@ desc "Run specs without coverage"
|
|
86
81
|
task :default => [:spec_no_cov]
|
87
82
|
Spec::Rake::SpecTask.new("spec_no_cov") do |t|
|
88
83
|
t.spec_files = FileList["spec/*_spec.rb"]
|
84
|
+
t.spec_opts = ["--format s"]
|
89
85
|
end
|
90
86
|
|
91
87
|
desc "Run rcov only"
|
92
88
|
Spec::Rake::SpecTask.new("rcov") do |t|
|
93
89
|
t.spec_files = FileList["spec/*_spec.rb"]
|
90
|
+
t.spec_opts = ["--format s"]
|
94
91
|
t.rcov = true
|
95
92
|
end
|
96
93
|
|
data/SETTINGS
CHANGED
@@ -24,6 +24,11 @@ resource files you are working with.
|
|
24
24
|
If you want to suppress them for some reason, set NWN_LIB_DEBUG to "0" or "off". Any
|
25
25
|
other value will indicate that you want to see the messages.
|
26
26
|
|
27
|
+
== NWN_LIB_DEBUG_TRACES
|
28
|
+
|
29
|
+
Set to non-nil to print full stack traces for each debug message emitted by NWN_LIB_DEBUG.
|
30
|
+
Default is not to print them, just the first non-library-frame.
|
31
|
+
|
27
32
|
== NWN_LIB_RESREF16
|
28
33
|
|
29
34
|
Set this to "1" if you are sure that you are only working with NWN1 files. This will
|
data/bin/nwn-gff
CHANGED
@@ -8,6 +8,7 @@ Thread.abort_on_exception = true
|
|
8
8
|
$options = {
|
9
9
|
:backup => nil,
|
10
10
|
:encoding => nil,
|
11
|
+
:out_encoding => nil,
|
11
12
|
:force => false,
|
12
13
|
:infile => '-',
|
13
14
|
:outfile => '-',
|
@@ -53,6 +54,10 @@ begin OptionParser.new do |o|
|
|
53
54
|
"files are encoded in" do |e|
|
54
55
|
$options[:encoding] = e
|
55
56
|
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
|
56
61
|
|
57
62
|
o.on "-1", "--nwn1", "Allow 16 byte resrefs." do
|
58
63
|
ENV['NWN_LIB_RESREF32'] = nil
|
@@ -115,9 +120,8 @@ end
|
|
115
120
|
$options[:informat] or fail "No input format specified."
|
116
121
|
$options[:outformat] or fail "No output format specified."
|
117
122
|
|
118
|
-
if $options[:encoding]
|
119
|
-
|
120
|
-
end
|
123
|
+
NWN.setting(:in_encoding, $options[:encoding]) if $options[:encoding]
|
124
|
+
NWN.setting(:out_encoding, $options[:out_encoding]) if $options[:out_encoding]
|
121
125
|
|
122
126
|
if :auto == $options[:informat]
|
123
127
|
$options[:informat] = NWN::Gff.guess_file_format($options[:infile].downcase)
|
data/lib/nwn/all.rb
CHANGED
@@ -15,4 +15,11 @@ rescue LoadError => e
|
|
15
15
|
NWN.log_debug "json support not available, install json or json_pure to enable"
|
16
16
|
end
|
17
17
|
require 'nwn/kivinen_support'
|
18
|
+
begin
|
19
|
+
require 'xml'
|
20
|
+
require 'nwn/xml_support'
|
21
|
+
rescue LoadError => e
|
22
|
+
NWN.log_debug "nxml and modpacker support not available, install libxml-ruby to enable"
|
23
|
+
end
|
24
|
+
|
18
25
|
require 'nwn/scripting'
|
data/lib/nwn/gff.rb
CHANGED
@@ -17,6 +17,60 @@ module NWN
|
|
17
17
|
# not exist.
|
18
18
|
class GffPathInvalidError < RuntimeError; end
|
19
19
|
|
20
|
+
# A namesoace for all Gff file format handlers.
|
21
|
+
module Handler
|
22
|
+
# Registers a new format handler that can deal with file formats for nwn-lib gff handling.
|
23
|
+
#
|
24
|
+
# [+name+] The name of this format as a symbol. Must be unique.
|
25
|
+
# [+fileFormatRegexp+] A regular expression matching file extensions for auto-detection.
|
26
|
+
# [+klass+] A object that responds to load(io) and dump(gff,io). load(io) reads from io
|
27
|
+
# and always returns a NWN::Gff::Struct describing a root struct, dump(gff, io)
|
28
|
+
# dumps the gff root struct in the handlers format to io and returns the number
|
29
|
+
# of bytes written.
|
30
|
+
# [+reads+] Boolean, indicates if this handler can read it's format and return gff data.
|
31
|
+
# [+writes+] Boolean, indicates if this handler can emit gff data in it's format.
|
32
|
+
def self.register name, fileFormatRegexp, klass, reads = true, writes = true
|
33
|
+
raise ArgumentError, "Handler for #{name.inspect} already registered." if
|
34
|
+
NWN::Gff::InputFormats[name.to_sym] || NWN::Gff::OutputFormats[name.to_sym]
|
35
|
+
NWN::Gff::InputFormats[name.to_sym] = klass if reads
|
36
|
+
NWN::Gff::OutputFormats[name.to_sym] = klass if writes
|
37
|
+
NWN::Gff::FileFormatGuesses[name.to_sym] = fileFormatRegexp
|
38
|
+
end
|
39
|
+
|
40
|
+
module Gff
|
41
|
+
def self.load io
|
42
|
+
NWN::Gff::Reader.read(io)
|
43
|
+
end
|
44
|
+
def self.dump data, io
|
45
|
+
NWN::Gff::Writer.dump(data, io)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module Pretty
|
50
|
+
def self.dump data, io
|
51
|
+
old = $> ; $> = StringIO.new
|
52
|
+
pp data.box
|
53
|
+
sz = $>.pos
|
54
|
+
$>.seek(0)
|
55
|
+
io.write $>.read
|
56
|
+
$> = old
|
57
|
+
sz
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module Marshal
|
62
|
+
def self.dump data, io
|
63
|
+
d = ::Marshal.dump(data)
|
64
|
+
io.write(d)
|
65
|
+
d.size
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.load io
|
69
|
+
::Marshal.load(io)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
20
74
|
# This hash lists all possible NWN::Gff::Field types.
|
21
75
|
Types = {
|
22
76
|
0 => :byte,
|
@@ -58,39 +112,22 @@ module NWN
|
|
58
112
|
:double => 'd',
|
59
113
|
}.freeze
|
60
114
|
|
61
|
-
# Registers a new format handler that can deal with file formats for nwn-lib gff handling.
|
62
|
-
def self.register_format_handler name, fileFormatRegexp, klass, reads = true, writes = true
|
63
|
-
InputFormats[name.to_sym] = klass if reads
|
64
|
-
OutputFormats[name.to_sym] = klass if writes
|
65
|
-
FileFormatGuesses[fileFormatRegexp] = name.to_sym
|
66
|
-
end
|
67
|
-
|
68
|
-
class Handler
|
69
|
-
def self.load io
|
70
|
-
NWN::Gff::Reader.read(io)
|
71
|
-
end
|
72
|
-
def self.dump data, io
|
73
|
-
NWN::Gff::Writer.dump(data, io)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class Pretty
|
78
|
-
def self.dump data, io
|
79
|
-
old = $> ; $> = io ; pp data.box ; $> = old
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
115
|
InputFormats = {}
|
84
116
|
OutputFormats = {}
|
85
117
|
FileFormatGuesses = {}
|
86
118
|
|
87
|
-
|
88
|
-
|
89
|
-
|
119
|
+
Handler.register :gff, /^(ut[cdeimpstw]|git|are|gic|mod|ifo|fac|ssf|dlg|itp|bic)$/, NWN::Gff::Handler::Gff
|
120
|
+
Handler.register :marshal, /^marshal$/, NWN::Gff::Handler::Marshal
|
121
|
+
Handler.register :pretty, /^$/, NWN::Gff::Handler::Pretty, false, true
|
90
122
|
|
91
123
|
def self.guess_file_format(filename)
|
92
124
|
extension = File.extname(filename.downcase)[1..-1]
|
93
|
-
FileFormatGuesses
|
125
|
+
matches = FileFormatGuesses.select {|fmt,rx| extension =~ rx }
|
126
|
+
if matches.size == 1
|
127
|
+
matches[0][0]
|
128
|
+
else
|
129
|
+
nil
|
130
|
+
end
|
94
131
|
end
|
95
132
|
|
96
133
|
def self.read(io, format)
|
data/lib/nwn/gff/field.rb
CHANGED
@@ -144,9 +144,9 @@ module NWN::Gff::Field
|
|
144
144
|
value.is_a?(Integer) && value >= 0 && value <= 0xffffffff
|
145
145
|
|
146
146
|
when :int64
|
147
|
-
value.is_a?(Integer) && value >= -
|
147
|
+
value.is_a?(Integer) && value >= -0x8000000000000000 && value <= 0x7fffffffffffffff
|
148
148
|
when :dword64
|
149
|
-
value.is_a?(Integer) && value >= 0 && value <=
|
149
|
+
value.is_a?(Integer) && value >= 0 && value <= 0xffffffffffffffff
|
150
150
|
|
151
151
|
when :float, :double
|
152
152
|
value.is_a?(Float)
|
@@ -228,10 +228,10 @@ module NWN::Gff::Field
|
|
228
228
|
case element.field_type
|
229
229
|
when :cexolocstr
|
230
230
|
element.field_value.each {|x,y|
|
231
|
-
element.field_value[x.to_i] = NWN
|
231
|
+
element.field_value[x.to_i] = NWN.iconv_native_to_gff(element.field_value.delete(x))
|
232
232
|
}
|
233
233
|
when :cexostr
|
234
|
-
element.field_value = NWN
|
234
|
+
element.field_value = NWN.iconv_native_to_gff(element.field_value)
|
235
235
|
|
236
236
|
when :list
|
237
237
|
element.field_value.each_with_index {|x,idx|
|
@@ -252,10 +252,10 @@ module NWN::Gff::Field
|
|
252
252
|
case field_type
|
253
253
|
when :cexolocstr
|
254
254
|
t['value'].each {|x,y|
|
255
|
-
t['value'][x] = NWN
|
255
|
+
t['value'][x] = NWN.iconv_gff_to_native(y)
|
256
256
|
}
|
257
257
|
when :cexostr
|
258
|
-
t['value'] = NWN
|
258
|
+
t['value'] = NWN.iconv_gff_to_native(t['value'])
|
259
259
|
end
|
260
260
|
t
|
261
261
|
end
|
data/lib/nwn/gff/reader.rb
CHANGED
@@ -29,9 +29,6 @@ class NWN::Gff::Reader
|
|
29
29
|
list_indices_offset, list_indices_count =
|
30
30
|
@io.e_read(160, "header").unpack("a4a4 VV VV VV VV VV VV")
|
31
31
|
|
32
|
-
raise GffError, "Unknown version #{version}; not a gff?" unless
|
33
|
-
version == "V3.2"
|
34
|
-
|
35
32
|
raise GffError, "struct offset at wrong place, not a gff?" unless
|
36
33
|
struct_offset == 56
|
37
34
|
|
data/lib/nwn/gff/struct.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
module NWN::Gff::Struct
|
4
4
|
DEFAULT_DATA_VERSION = "V3.2"
|
5
5
|
|
6
|
-
# The file version. Usually "V3.2"
|
7
|
-
# and
|
6
|
+
# The file version. Usually "V3.2". If not given in a source
|
7
|
+
# format, DEFAULT_DATA_VERSION is inferred and set for all structs.
|
8
8
|
attr_accessor :data_version
|
9
9
|
|
10
10
|
# GFF struct type. The default is 0xffffffff.
|
@@ -40,13 +40,14 @@ module NWN::Gff::Struct
|
|
40
40
|
|
41
41
|
# Overrides the data type (used by the built-in file format readers).
|
42
42
|
def data_type= k
|
43
|
-
|
43
|
+
k = nil if k == ""
|
44
|
+
NWN.log_debug("Setting explicit data_type for parented element") if k && @element
|
44
45
|
@data_type = k
|
45
46
|
end
|
46
47
|
|
47
48
|
def element= e #:nodoc:
|
48
49
|
@element = e
|
49
|
-
NWN.log_debug("Re-parenting a struct with explicit data_type #{@data_type.inspect}") if @data_type
|
50
|
+
NWN.log_debug("Re-parenting a struct with explicit data_type #{@data_type.inspect}") if e && @data_type
|
50
51
|
end
|
51
52
|
|
52
53
|
# Dump this struct as GFF binary data.
|
@@ -62,7 +63,7 @@ module NWN::Gff::Struct
|
|
62
63
|
#
|
63
64
|
# You can pass a block to this method, which will receive the newly-created
|
64
65
|
# Struct as the only argument.
|
65
|
-
def self.new struct_id = 0xffffffff, data_type = nil, data_version =
|
66
|
+
def self.new struct_id = 0xffffffff, data_type = nil, data_version = DEFAULT_DATA_VERSION
|
66
67
|
s = {}.extend(self)
|
67
68
|
s.struct_id = struct_id
|
68
69
|
s.data_type = data_type
|
@@ -228,6 +229,7 @@ module NWN::Gff::Struct
|
|
228
229
|
o.struct_id = o.delete('__struct_id')
|
229
230
|
o.data_type = o.delete('__data_type')
|
230
231
|
o.data_version = o.delete('__data_version')
|
232
|
+
o.data_version ||= NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
231
233
|
|
232
234
|
NWN.log_debug("Unboxed without a root data type") if
|
233
235
|
!parent && !o.data_type
|
@@ -250,7 +252,8 @@ module NWN::Gff::Struct
|
|
250
252
|
})
|
251
253
|
t.merge!({
|
252
254
|
'__data_version' => self.data_version,
|
253
|
-
}) if self.data_version && self.data_version !=
|
255
|
+
}) if self.data_version && self.data_version !=
|
256
|
+
NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
254
257
|
t.merge!({
|
255
258
|
'__data_type' => self.data_type
|
256
259
|
}) if @data_type
|
data/lib/nwn/json_support.rb
CHANGED
@@ -12,7 +12,7 @@ module NWN::Gff::Field
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
module NWN::Gff::JSON
|
15
|
+
module NWN::Gff::Handler::JSON
|
16
16
|
def self.load io
|
17
17
|
json = if io.respond_to?(:to_str)
|
18
18
|
io.to_str
|
@@ -26,12 +26,14 @@ module NWN::Gff::JSON
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.dump struct, io
|
29
|
-
if NWN.setting(:pretty_json)
|
30
|
-
|
29
|
+
d = if NWN.setting(:pretty_json)
|
30
|
+
::JSON.pretty_generate(struct)
|
31
31
|
else
|
32
|
-
|
32
|
+
::JSON.generate(struct)
|
33
33
|
end
|
34
|
+
io.puts d
|
35
|
+
d.size + 1
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
NWN::Gff.
|
39
|
+
NWN::Gff::Handler.register :json, /^json$/, NWN::Gff::Handler::JSON
|
data/lib/nwn/kivinen_support.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module NWN::Gff::Kivinen
|
1
|
+
module NWN::Gff::Handler::Kivinen
|
2
2
|
def self.load io
|
3
3
|
raise NotImplementedError, "Reading kivinen not supported"
|
4
4
|
end
|
@@ -9,6 +9,7 @@ module NWN::Gff::Kivinen
|
|
9
9
|
ret += "%s:\t%s\n" % [l, v]
|
10
10
|
end
|
11
11
|
io.puts ret
|
12
|
+
ret.size
|
12
13
|
end
|
13
14
|
|
14
15
|
# Parses +s+ as an arbitary GFF object and yields for each field found,
|
@@ -64,4 +65,4 @@ module NWN::Gff::Kivinen
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
67
|
-
NWN::Gff.
|
68
|
+
NWN::Gff::Handler.register :kivinen, /^k(ivinen)?$/, NWN::Gff::Handler::Kivinen, false, true
|
data/lib/nwn/settings.rb
CHANGED
@@ -2,7 +2,8 @@ require 'iconv'
|
|
2
2
|
|
3
3
|
module NWN
|
4
4
|
SETTING_DEFAULT_VALUES = {
|
5
|
-
'NWN_LIB_IN_ENCODING' => 'ISO-8859-1'
|
5
|
+
'NWN_LIB_IN_ENCODING' => 'ISO-8859-1',
|
6
|
+
'NWN_LIB_OUT_ENCODING' => 'UTF-8'
|
6
7
|
}
|
7
8
|
|
8
9
|
# This writes a internal warnings and debug messages to stderr.
|
@@ -17,9 +18,18 @@ module NWN
|
|
17
18
|
# Do not print debug messages if explicitly turned off
|
18
19
|
return false if [false, "off"].index(setting(:debug))
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
if NWN.setting(:debug_traces)
|
22
|
+
$stderr.puts "(nwn-lib): %s" % [msg]
|
23
|
+
$stderr.puts " " + caller.join("\n ") + "\n"
|
24
|
+
else
|
25
|
+
dir = File.expand_path(File.dirname(File.expand_path(__FILE__)) + "/../../")
|
26
|
+
pa = caller.reject {|x| x.index(dir) }[0]
|
27
|
+
pa ||= caller[0]
|
28
|
+
pa ||= "(no frames)"
|
29
|
+
pa = pa[(pa.size - 36) .. -1] if pa.size > 36
|
30
|
+
$stderr.puts "(nwn-lib) %s: %s" % [pa, msg]
|
31
|
+
end
|
32
|
+
|
23
33
|
true
|
24
34
|
end
|
25
35
|
|
@@ -29,7 +39,7 @@ module NWN
|
|
29
39
|
def self.setting sym, value = :_invalid_
|
30
40
|
name = "NWN_LIB_#{sym.to_s.upcase}"
|
31
41
|
if value != :_invalid_
|
32
|
-
ret =
|
42
|
+
ret = setting(sym)
|
33
43
|
ENV[name] = value.to_s if value != :_invalid_
|
34
44
|
ret
|
35
45
|
else
|
@@ -37,8 +47,25 @@ module NWN
|
|
37
47
|
end
|
38
48
|
end
|
39
49
|
|
40
|
-
|
41
|
-
|
50
|
+
IconvState = {} #:nodoc:
|
51
|
+
|
52
|
+
# Converts text from native format (such as json) to Gff (required by NWN).
|
53
|
+
def self.iconv_native_to_gff text
|
54
|
+
if IconvState[:in] != NWN.setting(:in_encoding) ||
|
55
|
+
IconvState[:out] != NWN.setting(:out_encoding)
|
56
|
+
IconvState[:in_i] = Iconv.new(NWN.setting(:in_encoding), NWN.setting(:out_encoding))
|
57
|
+
end
|
58
|
+
IconvState[:in_i].iconv(text)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Converts text from Gff format to native/external, such as json (usually UTF-8).
|
62
|
+
def self.iconv_gff_to_native text
|
63
|
+
if IconvState[:in] != NWN.setting(:in_encoding) ||
|
64
|
+
IconvState[:out] != NWN.setting(:out_encoding)
|
65
|
+
IconvState[:out_i] = Iconv.new(NWN.setting(:out_encoding), NWN.setting(:in_encoding))
|
66
|
+
end
|
67
|
+
IconvState[:out_i].iconv(text)
|
68
|
+
end
|
42
69
|
end
|
43
70
|
|
44
71
|
NWN::TwoDA::Cache.setup NWN.setting("2da_location") if
|
@@ -0,0 +1,202 @@
|
|
1
|
+
class NWN::Gff::Handler::XML
|
2
|
+
|
3
|
+
private
|
4
|
+
|
5
|
+
def struct_to_xml struct
|
6
|
+
s = XML::Node.new('struct')
|
7
|
+
case @format
|
8
|
+
when :nxml
|
9
|
+
s['id'] = struct.struct_id.to_s
|
10
|
+
s['dataType'] = struct.data_type if struct.data_type
|
11
|
+
s['dataVersion'] = struct.data_version if
|
12
|
+
struct.data_version != NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
13
|
+
when :modpacker
|
14
|
+
s['id'] = [struct.struct_id].pack("L").unpack("l")[0].to_s
|
15
|
+
s['nwnLibDataType'] = struct.data_type if struct.data_type
|
16
|
+
s['nwnLibDataVersion'] = struct.data_version if
|
17
|
+
struct.data_version != NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
18
|
+
end
|
19
|
+
|
20
|
+
struct.sort.each {|(k,v)|
|
21
|
+
s << field_to_xml(v)
|
22
|
+
}
|
23
|
+
s
|
24
|
+
end
|
25
|
+
|
26
|
+
def field_to_xml field
|
27
|
+
e = case @format
|
28
|
+
when :nxml
|
29
|
+
XML::Node.new('field')
|
30
|
+
when :modpacker
|
31
|
+
XML::Node.new('element')
|
32
|
+
end
|
33
|
+
e['name'] = field.field_label
|
34
|
+
e['type'] = case @format
|
35
|
+
when :modpacker
|
36
|
+
NWN::Gff::Types.index(field.field_type).to_s
|
37
|
+
when :nxml
|
38
|
+
field.field_type.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
vv = case field.field_type
|
42
|
+
when :cexolocstr
|
43
|
+
case @format
|
44
|
+
when :modpacker
|
45
|
+
e['value'] = [field.str_ref].pack("L").unpack("l")[0].to_s
|
46
|
+
when :nxml
|
47
|
+
e['strRef'] = field.str_ref.to_s if
|
48
|
+
field.str_ref != NWN::Gff::Cexolocstr::DEFAULT_STR_REF
|
49
|
+
end
|
50
|
+
|
51
|
+
field.field_value.each {|lid, tx|
|
52
|
+
e << se = XML::Node.new("localString")
|
53
|
+
se['languageId'] = lid.to_s
|
54
|
+
se['value'] = NWN.iconv_gff_to_native(tx)
|
55
|
+
}
|
56
|
+
|
57
|
+
when :cexostr
|
58
|
+
e['value'] = NWN.iconv_gff_to_native(field.field_value)
|
59
|
+
|
60
|
+
when :struct
|
61
|
+
e << struct_to_xml(field.field_value)
|
62
|
+
|
63
|
+
when :list
|
64
|
+
field.field_value.each {|ee|
|
65
|
+
e << struct_to_xml(ee)
|
66
|
+
}
|
67
|
+
|
68
|
+
else
|
69
|
+
e['value'] = field.field_value.to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
e
|
73
|
+
end
|
74
|
+
|
75
|
+
def xml_to_struct e, parent_data_version = nil
|
76
|
+
case @format
|
77
|
+
when :nxml
|
78
|
+
struct_id = e['id'] || raise("No struct id for: #{e.path}")
|
79
|
+
struct_id = struct_id.to_i
|
80
|
+
data_type = e['dataType']
|
81
|
+
parent_data_version ||= NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
82
|
+
data_version = e['dataVersion'] || parent_data_version
|
83
|
+
when :modpacker
|
84
|
+
struct_id = [e['id'].to_i].pack("l").unpack("L")[0]
|
85
|
+
data_type = e['nwnLibDataType']
|
86
|
+
data_version = e['nwnLibDataVersion'] || parent_data_version
|
87
|
+
end
|
88
|
+
|
89
|
+
st = NWN::Gff::Struct.new(struct_id, data_type, data_version)
|
90
|
+
e.each_element {|f|
|
91
|
+
xml_to_field(f, st, parent_data_version) if
|
92
|
+
f.name == case @format
|
93
|
+
when :modpacker ; 'element'
|
94
|
+
when :nxml ; 'field'
|
95
|
+
end
|
96
|
+
}
|
97
|
+
st
|
98
|
+
end
|
99
|
+
|
100
|
+
def xml_to_field field, struct, parent_data_version
|
101
|
+
name = field['name'] || raise("No name for field: #{field.path}")
|
102
|
+
type = case @format
|
103
|
+
when :nxml
|
104
|
+
field['type']
|
105
|
+
when :modpacker
|
106
|
+
NWN::Gff::Types[field['type'].to_i]
|
107
|
+
end || raise("No type for field: #{field.path}")
|
108
|
+
v = field['value']
|
109
|
+
|
110
|
+
f = struct.add_field(name, type,
|
111
|
+
case type.to_sym
|
112
|
+
when :cexostr
|
113
|
+
NWN.iconv_native_to_gff(v)
|
114
|
+
when :cexolocstr
|
115
|
+
Hash[field.children.reject {|x| x.node_type != XML::Node::ELEMENT_NODE }.map {|ee|
|
116
|
+
[ee['languageId'].to_i, NWN.iconv_native_to_gff(ee['value'] || '')]
|
117
|
+
}]
|
118
|
+
when :list
|
119
|
+
field.children.reject {|x| x.node_type != XML::Node::ELEMENT_NODE }.map {|ee|
|
120
|
+
xml_to_struct(ee, parent_data_version)
|
121
|
+
}
|
122
|
+
when :struct
|
123
|
+
xml_to_struct(field.children.select {|x|
|
124
|
+
x.node_type == XML::Node::ELEMENT_NODE
|
125
|
+
}[0], parent_data_version)
|
126
|
+
when :byte, :char, :word, :short, :dword, :int,
|
127
|
+
:dword64, :int64
|
128
|
+
v.to_i
|
129
|
+
when :float, :double
|
130
|
+
v.to_f
|
131
|
+
when :void, :resref
|
132
|
+
v
|
133
|
+
else
|
134
|
+
raise ArgumentError, "Invalid field type #{type.inspect}. Bug."
|
135
|
+
end
|
136
|
+
)
|
137
|
+
|
138
|
+
f.str_ref = case @format
|
139
|
+
when :nxml
|
140
|
+
field['strRef'] || NWN::Gff::Cexolocstr::DEFAULT_STR_REF
|
141
|
+
when :modpacker
|
142
|
+
[v.to_i].pack("l").unpack("L")[0]
|
143
|
+
end if f.is_a?(NWN::Gff::Cexolocstr)
|
144
|
+
|
145
|
+
f
|
146
|
+
end
|
147
|
+
|
148
|
+
public
|
149
|
+
|
150
|
+
def initialize fmt
|
151
|
+
@format = fmt
|
152
|
+
end
|
153
|
+
|
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
|
+
doc = XML::Parser.io(io)
|
160
|
+
root = doc.parse.root
|
161
|
+
ret = case @format
|
162
|
+
when :nxml
|
163
|
+
xml_to_struct(root)
|
164
|
+
when :modpacker
|
165
|
+
struct = root.children.select {|x| x.node_type == XML::Node::ELEMENT_NODE && x.name == 'struct' }[0]
|
166
|
+
xml_to_struct(struct, root['version'])
|
167
|
+
else
|
168
|
+
raise ArgumentError, "Unsupported XML format registered: #{@format.inspect}"
|
169
|
+
end
|
170
|
+
|
171
|
+
NWN.setting(:out_encoding, old_encoding)
|
172
|
+
ret
|
173
|
+
end
|
174
|
+
|
175
|
+
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
|
+
doc = XML::Document.new
|
181
|
+
doc.root = case @format
|
182
|
+
when :nxml
|
183
|
+
struct_to_xml(data)
|
184
|
+
when :modpacker
|
185
|
+
nd = XML::Node.new('gff')
|
186
|
+
nd['type'] = [data.data_type].pack("A4")
|
187
|
+
nd['version'] = [data.data_version].pack("A4")
|
188
|
+
nd << struct_to_xml(data)
|
189
|
+
nd
|
190
|
+
else
|
191
|
+
raise ArgumentError, "Unsupported XML format registered: #{@format.inspect}"
|
192
|
+
end
|
193
|
+
t = doc.to_s
|
194
|
+
io.write(t)
|
195
|
+
|
196
|
+
NWN.setting(:out_encoding, old_encoding)
|
197
|
+
t.size
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
NWN::Gff::Handler.register :nxml, /^nxml$/, NWN::Gff::Handler::XML.new(:nxml)
|
202
|
+
NWN::Gff::Handler.register :modpacker, nil, NWN::Gff::Handler::XML.new(:modpacker)
|
data/lib/nwn/yaml_support.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# This file contains all YAML-specific loading and dumping code.
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
-
|
4
|
+
module NWN::Gff::Handler::YAML
|
5
5
|
# These field types can never be inlined in YAML.
|
6
6
|
NonInlineableFields = [:struct, :list, :cexolocstr]
|
7
7
|
|
@@ -12,7 +12,9 @@ class NWN::Gff::YAML
|
|
12
12
|
YAML.load(io)
|
13
13
|
end
|
14
14
|
def self.dump data, io
|
15
|
-
|
15
|
+
d = data.to_yaml
|
16
|
+
io.puts d
|
17
|
+
d.size
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
@@ -46,7 +48,7 @@ end
|
|
46
48
|
|
47
49
|
module NWN::Gff::Struct
|
48
50
|
def to_yaml_type
|
49
|
-
"!#{NWN::Gff::YAML::Domain}/struct"
|
51
|
+
"!#{NWN::Gff::Handler::YAML::Domain}/struct"
|
50
52
|
end
|
51
53
|
|
52
54
|
def to_yaml(opts = {})
|
@@ -55,7 +57,7 @@ module NWN::Gff::Struct
|
|
55
57
|
# Inline certain structs that are small enough.
|
56
58
|
map.style = :inline if self.size <= 1 &&
|
57
59
|
self.values.select {|x|
|
58
|
-
NWN::Gff::YAML::NonInlineableFields.index(x['type'])
|
60
|
+
NWN::Gff::Handler::YAML::NonInlineableFields.index(x['type'])
|
59
61
|
}.size == 0
|
60
62
|
|
61
63
|
map.add('__' + 'data_type', @data_type) if @data_type
|
@@ -75,7 +77,7 @@ module NWN::Gff::Field
|
|
75
77
|
def to_yaml(opts = {})
|
76
78
|
YAML::quick_emit(nil, opts) do |out|
|
77
79
|
out.map(taguri, to_yaml_style) do |map|
|
78
|
-
map.style = :inline unless NWN::Gff::YAML::NonInlineableFields.index(self['type'])
|
80
|
+
map.style = :inline unless NWN::Gff::Handler::YAML::NonInlineableFields.index(self['type'])
|
79
81
|
map.add('type', self['type'])
|
80
82
|
map.add('str_ref', self['str_ref']) if has_str_ref?
|
81
83
|
map.add('value', self['value'])
|
@@ -85,7 +87,7 @@ module NWN::Gff::Field
|
|
85
87
|
end
|
86
88
|
|
87
89
|
# This parses the struct and extends all fields with their proper type.
|
88
|
-
YAML.add_domain_type(NWN::Gff::YAML::Domain,'struct') {|t,hash|
|
90
|
+
YAML.add_domain_type(NWN::Gff::Handler::YAML::Domain,'struct') {|t,hash|
|
89
91
|
struct = {}
|
90
92
|
struct.extend(NWN::Gff::Struct)
|
91
93
|
|
@@ -116,4 +118,4 @@ YAML.add_domain_type(NWN::Gff::YAML::Domain,'struct') {|t,hash|
|
|
116
118
|
struct
|
117
119
|
}
|
118
120
|
|
119
|
-
NWN::Gff.
|
121
|
+
NWN::Gff::Handler.register :yaml, /^(y|yml|yaml)$/, NWN::Gff::Handler::YAML
|
data/spec/gff_spec.rb
CHANGED
@@ -18,6 +18,8 @@ describe "Gff.read/write API" do
|
|
18
18
|
{
|
19
19
|
:gff => %w{utc utd ute uti utm utp uts utt utw git are gic mod ifo fac ssf dlg itp bic},
|
20
20
|
:yaml => %w{yml yaml},
|
21
|
+
:json => %w{json},
|
22
|
+
:nxml => %w{nxml},
|
21
23
|
:kivinen => %w{k kivinen},
|
22
24
|
:marshal => %w{marshal}
|
23
25
|
}.each {|expect, arr|
|
@@ -46,21 +48,28 @@ describe "Gff::*" do
|
|
46
48
|
t2.should == t
|
47
49
|
end
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
t2 = wellformed_verify v
|
57
|
-
t2.should == t
|
51
|
+
NWN::Gff::OutputFormats.keys.each do |fmt|
|
52
|
+
it "#{fmt} writes to io and returns the number of written bytes" do
|
53
|
+
t = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
54
|
+
out = StringIO.new
|
55
|
+
v = Gff.write(out, fmt, t)
|
56
|
+
v.should == out.pos
|
57
|
+
end
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
(NWN::Gff::OutputFormats.keys & NWN::Gff::InputFormats.keys).each do |fmt|
|
61
|
+
it "#{fmt} fails on not enough data" do
|
62
|
+
proc {
|
63
|
+
gff = Gff::Reader.read(StringIO.new WELLFORMED_GFF)
|
64
|
+
out = StringIO.new
|
65
|
+
Gff.write(out, fmt, gff)
|
66
|
+
size = out.pos
|
67
|
+
out.seek(0)
|
68
|
+
out.truncate(size - 20)
|
69
|
+
Gff.read(out, fmt)
|
70
|
+
}.should raise_error
|
71
|
+
end
|
72
|
+
|
64
73
|
end
|
65
74
|
|
66
75
|
end
|
data/spec/kivinen_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Gff::Struct" do
|
4
|
+
ReadWriteFormats = (NWN::Gff::OutputFormats.keys & NWN::Gff::InputFormats.keys)
|
5
|
+
NoRootNoMetadata = [:gff]
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@manual = Gff::Struct.new(0x0, 'root', 'V3.2') do |s|
|
9
|
+
s.add_struct 'a', Gff::Struct.new(0x1) do |a|
|
10
|
+
a.v.add_struct 'b', Gff::Struct.new(0x02) do |b|
|
11
|
+
b.v.add_field 'hi', :int, 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_write what, format
|
18
|
+
out = StringIO.new
|
19
|
+
Gff.write(out, format, what)
|
20
|
+
out.seek(0)
|
21
|
+
n = Gff.read(out, format)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has the proper data structure when building inline" do
|
25
|
+
@manual.data_type.should == 'root'
|
26
|
+
@manual.data_version.should == 'V3.2'
|
27
|
+
(@manual / 'a').path.should == '/a'
|
28
|
+
(@manual / 'a').v.path.should == '/a'
|
29
|
+
(@manual / 'a$').path.should == '/a'
|
30
|
+
(@manual / 'a/b$').path.should == '/a/b'
|
31
|
+
(@manual / 'a/b/hi').path.should == '/a/b/hi'
|
32
|
+
(@manual / 'a/b/hi$').should == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#data_type" do
|
36
|
+
ReadWriteFormats.each do |format|
|
37
|
+
it "#{format} keeps explicit root data types" do
|
38
|
+
@manual.data_type = 'EXPL'
|
39
|
+
n = read_write(@manual, format)
|
40
|
+
n.data_type.should == 'EXPL'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
(ReadWriteFormats - NoRootNoMetadata).each do |format|
|
45
|
+
it "#{format} keeps explicit non-root data types" do
|
46
|
+
(@manual / 'a/b$').data_type = 'EXPL'
|
47
|
+
n = read_write(@manual, format)
|
48
|
+
(n / 'a/b$').data_type.should == 'EXPL'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#data_version" do
|
54
|
+
ReadWriteFormats.each do |format|
|
55
|
+
it "#{format} keeps explicit root data version" do
|
56
|
+
@manual.data_version = 'EXPL'
|
57
|
+
n = read_write(@manual, format)
|
58
|
+
n.data_version.should == 'EXPL'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
(ReadWriteFormats - NoRootNoMetadata).each do |format|
|
63
|
+
it "#{format} keeps explicit non-root data version" do
|
64
|
+
(@manual / 'a/b$').data_version = 'EXPL'
|
65
|
+
n = read_write(@manual, format)
|
66
|
+
(n / 'a/b$').data_version.should == 'EXPL'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
ReadWriteFormats.each do |format|
|
71
|
+
it "#{format} reads implicit data_version as DEFAULT_DATA_VERSION" do
|
72
|
+
n = read_write(@manual, format)
|
73
|
+
|
74
|
+
(@manual / 'a/b$').data_version.should == NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
75
|
+
@manual.data_version.should == NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
76
|
+
(n / 'a/b$').data_version.should == NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
77
|
+
n.data_version.should == NWN::Gff::Struct::DEFAULT_DATA_VERSION
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
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.4.
|
4
|
+
version: 0.4.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernhard Stoeckner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-15 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -36,54 +36,55 @@ files:
|
|
36
36
|
- CHANGELOG
|
37
37
|
- README
|
38
38
|
- Rakefile
|
39
|
-
- bin/nwn-gff
|
40
39
|
- bin/nwn-dsl
|
41
|
-
- bin/nwn-
|
40
|
+
- bin/nwn-gff
|
42
41
|
- bin/nwn-irb
|
43
|
-
-
|
42
|
+
- bin/nwn-erf
|
43
|
+
- spec/kivinen_expect.rb
|
44
|
+
- spec/wellformed_gff.bic
|
44
45
|
- spec/gff_spec.rb
|
46
|
+
- spec/struct_data_type_version_spec.rb
|
47
|
+
- spec/res_spec.rb
|
48
|
+
- spec/erf_spec.rb
|
45
49
|
- spec/key_spec.rb
|
46
|
-
- spec/
|
47
|
-
- spec/bin_erf_spec.rb
|
48
|
-
- spec/kivinen_expect.rb
|
50
|
+
- spec/kivinen_spec.rb
|
49
51
|
- spec/field_spec.rb
|
50
52
|
- spec/cexolocstr_spec.rb
|
51
|
-
- spec/kivinen_spec.rb
|
52
|
-
- spec/erf_spec.rb
|
53
53
|
- spec/struct_spec.rb
|
54
|
-
- spec/
|
54
|
+
- spec/spec_helper.rb
|
55
55
|
- spec/tlk_spec.rb
|
56
56
|
- spec/json_spec.rb
|
57
|
+
- spec/bin_dsl_spec.rb
|
58
|
+
- spec/bin_gff_spec.rb
|
59
|
+
- spec/bin_erf_spec.rb
|
57
60
|
- spec/twoda_spec.rb
|
58
|
-
-
|
59
|
-
- spec/data_type_spec.rb
|
60
|
-
- spec/wellformed_gff.bic
|
61
|
-
- lib/nwn/erf.rb
|
62
|
-
- lib/nwn/json_support.rb
|
63
|
-
- lib/nwn/io.rb
|
64
|
-
- lib/nwn/settings.rb
|
61
|
+
- lib/nwn/scripting.rb
|
65
62
|
- lib/nwn/key.rb
|
66
|
-
- lib/nwn/all.rb
|
67
|
-
- lib/nwn/res.rb
|
68
63
|
- lib/nwn/twoda.rb
|
69
|
-
- lib/nwn/
|
64
|
+
- lib/nwn/json_support.rb
|
65
|
+
- lib/nwn/erf.rb
|
66
|
+
- lib/nwn/kivinen_support.rb
|
67
|
+
- lib/nwn/settings.rb
|
70
68
|
- lib/nwn/gff.rb
|
71
69
|
- lib/nwn/yaml_support.rb
|
72
|
-
- lib/nwn/
|
73
|
-
- lib/nwn/
|
74
|
-
- lib/nwn/
|
75
|
-
- lib/nwn/
|
76
|
-
- lib/nwn/
|
70
|
+
- lib/nwn/xml_support.rb
|
71
|
+
- lib/nwn/tlk.rb
|
72
|
+
- lib/nwn/io.rb
|
73
|
+
- lib/nwn/res.rb
|
74
|
+
- lib/nwn/all.rb
|
75
|
+
- lib/nwn/gff/field.rb
|
77
76
|
- lib/nwn/gff/reader.rb
|
78
77
|
- lib/nwn/gff/cexolocstr.rb
|
79
|
-
- lib/nwn/gff/
|
78
|
+
- lib/nwn/gff/struct.rb
|
79
|
+
- lib/nwn/gff/list.rb
|
80
|
+
- lib/nwn/gff/writer.rb
|
80
81
|
- tools/verify.sh
|
81
82
|
- tools/migrate_03x_to_04x.sh
|
82
83
|
- scripts/truncate_floats.rb
|
84
|
+
- scripts/reformat_2da
|
83
85
|
- scripts/clean_locstrs.rb
|
84
|
-
- scripts/debug_check_objid.rb
|
85
86
|
- scripts/extract_all_items.rb
|
86
|
-
- scripts/
|
87
|
+
- scripts/debug_check_objid.rb
|
87
88
|
- BINARIES
|
88
89
|
- HOWTO
|
89
90
|
- SCRIPTING
|
data/spec/data_type_spec.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe "Gff::Struct#data_type" do
|
4
|
-
|
5
|
-
before(:each) do
|
6
|
-
@manual = Gff::Struct.new(0x0, 'root', 'V3.1') do |s|
|
7
|
-
s.add_struct 'a', Gff::Struct.new(0x1) do |a|
|
8
|
-
a.v.add_struct 'b', Gff::Struct.new(0x02) do |b|
|
9
|
-
b.v.add_field 'hi', :int, 1
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
it "has the proper data types when building inline" do
|
16
|
-
verify @manual
|
17
|
-
end
|
18
|
-
|
19
|
-
unless Gff::InputFormats[:json] && Gff::OutputFormats[:json]
|
20
|
-
$stderr.puts "Partial or no json support, not running json specs!"
|
21
|
-
else
|
22
|
-
|
23
|
-
it "keeps explicit data types for json" do
|
24
|
-
@manual['a'].v['b'].v.data_type = 'EXPLICIT'
|
25
|
-
json = StringIO.new
|
26
|
-
Gff.write(json, :json, @manual)
|
27
|
-
json.seek(0)
|
28
|
-
n = Gff.read(json, :json)
|
29
|
-
n['a'].v.path.should == '/a'
|
30
|
-
n['a'].v.data_type.should == nil
|
31
|
-
n['a'].v['b'].v.data_type.should == 'EXPLICIT'
|
32
|
-
end
|
33
|
-
|
34
|
-
it "has the proper data type when reading from json" do
|
35
|
-
struct = <<EOS
|
36
|
-
{
|
37
|
-
"a": {
|
38
|
-
"type": "struct",
|
39
|
-
"value": {
|
40
|
-
"b": {
|
41
|
-
"type": "struct",
|
42
|
-
"value": {
|
43
|
-
"hi": {
|
44
|
-
"type": "int",
|
45
|
-
"value": 1
|
46
|
-
},
|
47
|
-
"__struct_id": 2
|
48
|
-
}
|
49
|
-
},
|
50
|
-
"__struct_id": 1
|
51
|
-
}
|
52
|
-
},
|
53
|
-
"__data_version": "V3.1",
|
54
|
-
"__data_type": "root",
|
55
|
-
"__struct_id": 0
|
56
|
-
}
|
57
|
-
EOS
|
58
|
-
|
59
|
-
struct = Gff.read(StringIO.new(struct), :json)
|
60
|
-
|
61
|
-
verify struct
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
it "keeps explicit data types for yaml" do
|
67
|
-
(@manual / 'a/b').v.data_type = 'EXPLICIT'
|
68
|
-
json = StringIO.new
|
69
|
-
Gff.write(json, :yaml, @manual)
|
70
|
-
json.seek(0)
|
71
|
-
n = Gff.read(json, :yaml)
|
72
|
-
(n / 'a/b/hi').path.should == "/a/b/hi"
|
73
|
-
(n / 'a$').data_type.should == nil
|
74
|
-
(n / 'a/b$').data_type.should == "EXPLICIT"
|
75
|
-
end
|
76
|
-
|
77
|
-
it "has the proper data type when reading from yaml" do
|
78
|
-
struct = <<EOS
|
79
|
-
--- !nwn-lib.elv.es,2008-12/struct
|
80
|
-
__data_type: root
|
81
|
-
__data_version: V3.1
|
82
|
-
__struct_id: 0
|
83
|
-
a:
|
84
|
-
type: :struct
|
85
|
-
value: !nwn-lib.elv.es,2008-12/struct
|
86
|
-
__data_type: ATYPE
|
87
|
-
__struct_id: 1
|
88
|
-
b:
|
89
|
-
type: :struct
|
90
|
-
value: !nwn-lib.elv.es,2008-12/struct {__data_type: BTYPE, __struct_id: 2, hi: {type: :int, value: 1}}
|
91
|
-
EOS
|
92
|
-
struct = Gff.read(StringIO.new(struct), :yaml)
|
93
|
-
|
94
|
-
verify struct
|
95
|
-
end
|
96
|
-
|
97
|
-
it "has the proper data type when reading from yaml with overriden data_type" do
|
98
|
-
struct = <<EOS
|
99
|
-
--- !nwn-lib.elv.es,2008-12/struct
|
100
|
-
__data_type: root
|
101
|
-
__data_version: V3.1
|
102
|
-
__struct_id: 0
|
103
|
-
a:
|
104
|
-
type: :struct
|
105
|
-
value: !nwn-lib.elv.es,2008-12/struct
|
106
|
-
__data_type: DTYPE
|
107
|
-
__struct_id: 1
|
108
|
-
b:
|
109
|
-
type: :struct
|
110
|
-
value: !nwn-lib.elv.es,2008-12/struct {__data_type: BTYPE, __struct_id: 2, hi: {type: :int, value: 1}}
|
111
|
-
EOS
|
112
|
-
struct = Gff.read(StringIO.new(struct), :yaml)
|
113
|
-
|
114
|
-
(struct / 'a$').data_type.should == 'DTYPE'
|
115
|
-
(struct / 'a$').path.should == '/a'
|
116
|
-
end
|
117
|
-
|
118
|
-
def verify struct
|
119
|
-
struct.data_type.should == 'root'
|
120
|
-
struct.data_version.should == 'V3.1'
|
121
|
-
(struct / 'a').path.should == '/a'
|
122
|
-
(struct / 'a').v.path.should == '/a'
|
123
|
-
(struct / 'a$').path.should == '/a'
|
124
|
-
(struct / 'a/b$').path.should == '/a/b'
|
125
|
-
(struct / 'a/b/hi').path.should == '/a/b/hi'
|
126
|
-
(struct / 'a/b/hi$').should == 1
|
127
|
-
end
|
128
|
-
end
|