nwn-lib 0.4.11 → 0.4.12
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.
- 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
|