offroad 0.0.2 → 0.0.3

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.
Files changed (61) hide show
  1. data/LICENSE +674 -674
  2. data/README.rdoc +29 -29
  3. data/Rakefile +75 -75
  4. data/TODO +42 -42
  5. data/lib/app/models/offroad/group_state.rb +85 -85
  6. data/lib/app/models/offroad/mirror_info.rb +53 -53
  7. data/lib/app/models/offroad/model_state.rb +36 -36
  8. data/lib/app/models/offroad/received_record_state.rb +115 -115
  9. data/lib/app/models/offroad/sendable_record_state.rb +91 -91
  10. data/lib/app/models/offroad/system_state.rb +33 -33
  11. data/lib/cargo_streamer.rb +222 -222
  12. data/lib/controller_extensions.rb +74 -74
  13. data/lib/exceptions.rb +16 -16
  14. data/lib/migrate/20100512164608_create_offroad_tables.rb +72 -72
  15. data/lib/mirror_data.rb +376 -376
  16. data/lib/model_extensions.rb +378 -377
  17. data/lib/module_funcs.rb +94 -94
  18. data/lib/offroad.rb +41 -41
  19. data/lib/version.rb +3 -3
  20. data/lib/view_helper.rb +7 -7
  21. data/templates/offline.rb +36 -36
  22. data/templates/offline_database.yml +7 -7
  23. data/templates/offroad.yml +6 -6
  24. data/test/app_root/app/controllers/application_controller.rb +2 -2
  25. data/test/app_root/app/controllers/group_controller.rb +28 -28
  26. data/test/app_root/app/models/global_record.rb +10 -10
  27. data/test/app_root/app/models/group.rb +12 -12
  28. data/test/app_root/app/models/group_owned_record.rb +68 -68
  29. data/test/app_root/app/models/guest.rb +7 -7
  30. data/test/app_root/app/models/subrecord.rb +12 -12
  31. data/test/app_root/app/models/unmirrored_record.rb +4 -4
  32. data/test/app_root/app/views/group/download_down_mirror.html.erb +3 -3
  33. data/test/app_root/app/views/group/download_initial_down_mirror.html.erb +3 -3
  34. data/test/app_root/app/views/group/download_up_mirror.html.erb +5 -5
  35. data/test/app_root/app/views/layouts/mirror.html.erb +8 -8
  36. data/test/app_root/config/boot.rb +115 -115
  37. data/test/app_root/config/database-pg.yml +8 -8
  38. data/test/app_root/config/database.yml +5 -5
  39. data/test/app_root/config/environment.rb +24 -24
  40. data/test/app_root/config/environments/test.rb +17 -17
  41. data/test/app_root/config/offroad.yml +6 -6
  42. data/test/app_root/config/routes.rb +4 -4
  43. data/test/app_root/db/migrate/20100529235049_create_tables.rb +64 -64
  44. data/test/app_root/lib/common_hobo.rb +15 -15
  45. data/test/app_root/vendor/plugins/offroad/init.rb +2 -2
  46. data/test/functional/mirror_operations_test.rb +148 -148
  47. data/test/test_helper.rb +453 -453
  48. data/test/unit/app_state_tracking_test.rb +275 -275
  49. data/test/unit/cargo_streamer_test.rb +332 -332
  50. data/test/unit/global_data_test.rb +102 -102
  51. data/test/unit/group_controller_test.rb +152 -152
  52. data/test/unit/group_data_test.rb +442 -435
  53. data/test/unit/group_single_test.rb +136 -136
  54. data/test/unit/hobo_permissions_test.rb +57 -57
  55. data/test/unit/mirror_data_test.rb +1283 -1283
  56. data/test/unit/mirror_info_test.rb +31 -31
  57. data/test/unit/module_funcs_test.rb +37 -37
  58. data/test/unit/pathological_model_test.rb +62 -62
  59. data/test/unit/test_framework_test.rb +86 -86
  60. data/test/unit/unmirrored_data_test.rb +14 -14
  61. metadata +6 -8
@@ -1,33 +1,33 @@
1
- require 'forwardable'
2
-
3
- module Offroad
4
- private
5
-
6
- # State of the Offroad-managed app as a whole; there should only be one record in this table
7
- # Attributes of that record can be read via the class methods of this class
8
- class SystemState < ActiveRecord::Base
9
- set_table_name "offroad_system_state"
10
-
11
- # Create validators and class-level attribute getters for the columns that contain system settings
12
- extend SingleForwardable
13
- for column in columns
14
- sym = column.name.to_sym
15
- next if sym == :id
16
- def_delegator :instance_record, sym
17
- end
18
-
19
- def self.increment_mirror_version
20
- self.increment_counter(:current_mirror_version, instance_record.id)
21
- end
22
-
23
- # Returns the singleton record, first creating it if necessary
24
- def self.instance_record
25
- sys_state = first
26
- if sys_state
27
- return sys_state
28
- else
29
- return create(:current_mirror_version => 1)
30
- end
31
- end
32
- end
33
- end
1
+ require 'forwardable'
2
+
3
+ module Offroad
4
+ private
5
+
6
+ # State of the Offroad-managed app as a whole; there should only be one record in this table
7
+ # Attributes of that record can be read via the class methods of this class
8
+ class SystemState < ActiveRecord::Base
9
+ set_table_name "offroad_system_state"
10
+
11
+ # Create validators and class-level attribute getters for the columns that contain system settings
12
+ extend SingleForwardable
13
+ for column in columns
14
+ sym = column.name.to_sym
15
+ next if sym == :id
16
+ def_delegator :instance_record, sym
17
+ end
18
+
19
+ def self.increment_mirror_version
20
+ self.increment_counter(:current_mirror_version, instance_record.id)
21
+ end
22
+
23
+ # Returns the singleton record, first creating it if necessary
24
+ def self.instance_record
25
+ sys_state = first
26
+ if sys_state
27
+ return sys_state
28
+ else
29
+ return create(:current_mirror_version => 1)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,222 +1,222 @@
1
- require 'zlib'
2
- require 'digest/md5'
3
-
4
- require 'exceptions'
5
-
6
- module Offroad
7
- class CargoStreamerError < DataError
8
- end
9
-
10
- private
11
-
12
- # Class for encoding data to, and extracting data from, specially-formatted HTML comments which are called "cargo sections".
13
- # Each such section has a name, an md5sum for verification, and some base64-encoded zlib-compressed json data.
14
- # Multiple cargo sections can have the same name; when the cargo is later read, requests for that name will be yielded each section in turn.
15
- # The data must always be in the form of arrays of ActiveRecord, or things that walk sufficiently like ActiveRecord
16
- class CargoStreamer
17
- # Models which are to be encoded need to have a method safe_to_load_from_cargo_stream? that returns true.
18
-
19
- # Creates a new CargoStreamer on the given stream, which will be used in the given mode (must be "w" or "r").
20
- # If the mode is "r", the file is immediately scanned to determine what cargo it contains.
21
- def initialize(ioh, mode)
22
- raise CargoStreamerError.new("Invalid mode: must be 'w' or 'r'") unless ["w", "r"].include?(mode)
23
- @mode = mode
24
-
25
- if ioh.is_a? String
26
- raise CargoStreamerError.new("Cannot accept string as ioh in write mode") unless @mode == "r"
27
- @ioh = StringIO.new(ioh, "r")
28
- else
29
- @ioh = ioh
30
- end
31
-
32
- scan_for_cargo if @mode == "r"
33
- end
34
-
35
- # Writes a cargo section with the given name and value to the IO stream.
36
- # Options:
37
- # * :human_readable => true - Before writing the cargo section, writes a comment with human-readable data.
38
- # * :include => [:assoc, :other_assoc] - Includes these first-level associations in the encoded data
39
- def write_cargo_section(name, value, options = {})
40
- raise CargoStreamerError.new("Mode must be 'w' to write cargo data") unless @mode == "w"
41
- raise CargoStreamerError.new("CargoStreamer section names must be strings") unless name.is_a? String
42
- raise CargoStreamerError.new("Invalid cargo name '" + name + "'") unless name == clean_for_html_comment(name)
43
- raise CargoStreamerError.new("Cargo name cannot include newlines") if name.include?("\n")
44
- raise CargoStreamerError.new("Value must be an array") unless value.is_a? Array
45
- [:to_xml, :attributes=, :valid?].each do |message|
46
- unless value.all? { |e| e.respond_to? message }
47
- raise CargoStreamerError.new("All elements must respond to #{message}")
48
- end
49
- end
50
- unless value.all? { |e| e.class.respond_to?(:safe_to_load_from_cargo_stream?) && e.class.safe_to_load_from_cargo_stream? }
51
- raise CargoStreamerError.new("All element classes must be models which are safe_to_load_from_cargo_stream")
52
- end
53
-
54
- unless options[:skip_validation]
55
- unless value.all?(&:valid?)
56
- raise CargoStreamerError.new("All elements must be valid")
57
- end
58
- end
59
-
60
- if options[:human_readable]
61
- human_data = value.map{ |rec|
62
- rec.attributes.map{ |k, v| "#{k.to_s.titleize}: #{v.to_s}" }.join("\n")
63
- }.join("\n\n")
64
- @ioh.write "<!--\n"
65
- @ioh.write name.titleize + "\n"
66
- @ioh.write "\n"
67
- @ioh.write clean_for_html_comment(human_data) + "\n"
68
- @ioh.write "-->\n"
69
- end
70
-
71
- name = name.chomp
72
-
73
- assoc_list = options[:include] || []
74
-
75
- xml = Builder::XmlMarkup.new
76
- xml_data = "<records>%s</records>" % value.map {
77
- |r| r.to_xml(
78
- :skip_instruct => true,
79
- :skip_types => true,
80
- :root => "record",
81
- :indent => 0,
82
- :include => assoc_list
83
- ) do |xml|
84
- xml.cargo_streamer_type r.class.name
85
- assoc_info = assoc_list.reject{|a| r.send(a) == nil}.map{|a| "#{a.to_s}=#{r.send(a).class.name}"}.join(",")
86
- xml.cargo_streamer_includes assoc_info
87
- end
88
- }.join()
89
- deflated_data = Zlib::Deflate::deflate(xml_data)
90
- b64_data = Base64.encode64(deflated_data).chomp
91
- digest = Digest::MD5::hexdigest(deflated_data).chomp
92
-
93
- @ioh.write CARGO_BEGIN + "\n"
94
- @ioh.write name + "\n"
95
- @ioh.write digest + "\n"
96
- @ioh.write b64_data + "\n"
97
- @ioh.write CARGO_END + "\n"
98
- end
99
-
100
- # Returns a list of cargo section names available to be read
101
- def cargo_section_names
102
- return @cargo_locations.keys
103
- end
104
-
105
- # Returns true if cargo with a given name is available
106
- def has_cargo_named?(name)
107
- return @cargo_locations.has_key? name
108
- end
109
-
110
- # Reads, verifies, decodes, and returns the first cargo section with a given name
111
- def first_cargo_section(name)
112
- each_cargo_section(name) do |data|
113
- return data
114
- end
115
- end
116
-
117
- # Returns the first element from the return value of first_cargo_section
118
- def first_cargo_element(name)
119
- arr = first_cargo_section(name)
120
- return (arr && arr.size > 0) ? arr[0] : nil
121
- end
122
-
123
- # Reads, verifies, and decodes each cargo section with a given name, passing each section's decoded data to the block
124
- def each_cargo_section(name)
125
- raise CargoStreamerError.new("Mode must be 'r' to read cargo data") unless @mode == "r"
126
- locations = @cargo_locations[name] or return
127
- locations.each do |seek_location|
128
- @ioh.seek(seek_location)
129
- digest = ""
130
- encoded_data = ""
131
- @ioh.each_line do |line|
132
- line.chomp!
133
- if line == CARGO_END
134
- break
135
- elsif digest == ""
136
- digest = line
137
- else
138
- encoded_data += line
139
- end
140
- end
141
-
142
- yield verify_and_decode_cargo(digest, encoded_data)
143
- end
144
- end
145
-
146
- private
147
-
148
- def scan_for_cargo
149
- # Key is cargo section name as String, value is array of seek locations to digests for that section
150
- @cargo_locations = {}
151
- @ioh.rewind
152
-
153
- in_cargo = false
154
- found_name = false
155
- @ioh.each_line do |line|
156
- line.chomp!
157
- if in_cargo
158
- if line.include? CARGO_END
159
- in_cargo = false
160
- found_name = false
161
- else
162
- unless found_name
163
- @cargo_locations[line] ||= []
164
- @cargo_locations[line] << @ioh.tell
165
- found_name = true
166
- end
167
- end
168
- else
169
- if line.include? CARGO_BEGIN
170
- in_cargo = true
171
- end
172
- end
173
- end
174
- raise CargoStreamerError.new("Input contained un-terminated cargo section") unless in_cargo == false
175
-
176
- @ioh.rewind
177
- end
178
-
179
- def clean_for_html_comment(s)
180
- s.to_s.gsub("--", "__").gsub("<", "[").gsub(">", "]")
181
- end
182
-
183
- def compose_record_from_hash(model_class_name, attrs_hash)
184
- model_class = model_class_name.constantize
185
- raise "Class #{model_class_name} does not have cargo safety method" unless model_class.respond_to? :safe_to_load_from_cargo_stream?
186
- raise "Class #{model_class_name} is not safe_to_load_from_cargo_stream" unless model_class.safe_to_load_from_cargo_stream?
187
-
188
- rec = model_class.new
189
- rec.send(:attributes=, attrs_hash, false) # No attr_accessible check like this, so all attributes can be set
190
- rec.readonly! # rec is just source data for creation of a "real" record; it shouldn't be saveable itself
191
- rec
192
- end
193
-
194
- def verify_and_decode_cargo(digest, b64_data)
195
- deflated_data = Base64.decode64(b64_data)
196
- raise "MD5 check failure" unless Digest::MD5::hexdigest(deflated_data) == digest
197
-
198
- # Even though we encoded an Array with Array#to_xml, there is no Array#from_xml
199
- # So, we have to use Hash#from_xml
200
- records = Hash.from_xml(Zlib::Inflate::inflate(deflated_data))["records"]["record"]
201
- raise "Decode failure, unable to find records key" unless records != nil
202
- records = [records] unless records.is_a?(Array)
203
- return records.map do |attrs_hash|
204
- raise "Unable to find record type" unless attrs_hash.has_key?("cargo_streamer_type")
205
- class_name = attrs_hash.delete("cargo_streamer_type")
206
-
207
- raise "Unable to find includes list" unless attrs_hash.has_key?("cargo_streamer_includes")
208
- (attrs_hash.delete("cargo_streamer_includes") || "").split(",").each do |assoc_info|
209
- assoc_name, i_class_name = assoc_info.split("=")
210
- attrs_hash[assoc_name] = compose_record_from_hash(i_class_name, attrs_hash[assoc_name])
211
- end
212
-
213
- compose_record_from_hash(class_name, attrs_hash)
214
- end
215
- rescue StandardError => e
216
- raise CargoStreamerError.new("Corrupted data : #{e.class.to_s} : #{e.to_s}")
217
- end
218
-
219
- CARGO_BEGIN = "<!-- CARGO SEGMENT"
220
- CARGO_END = "END CARGO SEGMENT -->"
221
- end
222
- end
1
+ require 'zlib'
2
+ require 'digest/md5'
3
+
4
+ require 'exceptions'
5
+
6
+ module Offroad
7
+ class CargoStreamerError < DataError
8
+ end
9
+
10
+ private
11
+
12
+ # Class for encoding data to, and extracting data from, specially-formatted HTML comments which are called "cargo sections".
13
+ # Each such section has a name, an md5sum for verification, and some base64-encoded zlib-compressed json data.
14
+ # Multiple cargo sections can have the same name; when the cargo is later read, requests for that name will be yielded each section in turn.
15
+ # The data must always be in the form of arrays of ActiveRecord, or things that walk sufficiently like ActiveRecord
16
+ class CargoStreamer
17
+ # Models which are to be encoded need to have a method safe_to_load_from_cargo_stream? that returns true.
18
+
19
+ # Creates a new CargoStreamer on the given stream, which will be used in the given mode (must be "w" or "r").
20
+ # If the mode is "r", the file is immediately scanned to determine what cargo it contains.
21
+ def initialize(ioh, mode)
22
+ raise CargoStreamerError.new("Invalid mode: must be 'w' or 'r'") unless ["w", "r"].include?(mode)
23
+ @mode = mode
24
+
25
+ if ioh.is_a? String
26
+ raise CargoStreamerError.new("Cannot accept string as ioh in write mode") unless @mode == "r"
27
+ @ioh = StringIO.new(ioh, "r")
28
+ else
29
+ @ioh = ioh
30
+ end
31
+
32
+ scan_for_cargo if @mode == "r"
33
+ end
34
+
35
+ # Writes a cargo section with the given name and value to the IO stream.
36
+ # Options:
37
+ # * :human_readable => true - Before writing the cargo section, writes a comment with human-readable data.
38
+ # * :include => [:assoc, :other_assoc] - Includes these first-level associations in the encoded data
39
+ def write_cargo_section(name, value, options = {})
40
+ raise CargoStreamerError.new("Mode must be 'w' to write cargo data") unless @mode == "w"
41
+ raise CargoStreamerError.new("CargoStreamer section names must be strings") unless name.is_a? String
42
+ raise CargoStreamerError.new("Invalid cargo name '" + name + "'") unless name == clean_for_html_comment(name)
43
+ raise CargoStreamerError.new("Cargo name cannot include newlines") if name.include?("\n")
44
+ raise CargoStreamerError.new("Value must be an array") unless value.is_a? Array
45
+ [:to_xml, :attributes=, :valid?].each do |message|
46
+ unless value.all? { |e| e.respond_to? message }
47
+ raise CargoStreamerError.new("All elements must respond to #{message}")
48
+ end
49
+ end
50
+ unless value.all? { |e| e.class.respond_to?(:safe_to_load_from_cargo_stream?) && e.class.safe_to_load_from_cargo_stream? }
51
+ raise CargoStreamerError.new("All element classes must be models which are safe_to_load_from_cargo_stream")
52
+ end
53
+
54
+ unless options[:skip_validation]
55
+ unless value.all?(&:valid?)
56
+ raise CargoStreamerError.new("All elements must be valid")
57
+ end
58
+ end
59
+
60
+ if options[:human_readable]
61
+ human_data = value.map{ |rec|
62
+ rec.attributes.map{ |k, v| "#{k.to_s.titleize}: #{v.to_s}" }.join("\n")
63
+ }.join("\n\n")
64
+ @ioh.write "<!--\n"
65
+ @ioh.write name.titleize + "\n"
66
+ @ioh.write "\n"
67
+ @ioh.write clean_for_html_comment(human_data) + "\n"
68
+ @ioh.write "-->\n"
69
+ end
70
+
71
+ name = name.chomp
72
+
73
+ assoc_list = options[:include] || []
74
+
75
+ xml = Builder::XmlMarkup.new
76
+ xml_data = "<records>%s</records>" % value.map {
77
+ |r| r.to_xml(
78
+ :skip_instruct => true,
79
+ :skip_types => true,
80
+ :root => "record",
81
+ :indent => 0,
82
+ :include => assoc_list
83
+ ) do |xml|
84
+ xml.cargo_streamer_type r.class.name
85
+ assoc_info = assoc_list.reject{|a| r.send(a) == nil}.map{|a| "#{a.to_s}=#{r.send(a).class.name}"}.join(",")
86
+ xml.cargo_streamer_includes assoc_info
87
+ end
88
+ }.join()
89
+ deflated_data = Zlib::Deflate::deflate(xml_data)
90
+ b64_data = Base64.encode64(deflated_data).chomp
91
+ digest = Digest::MD5::hexdigest(deflated_data).chomp
92
+
93
+ @ioh.write CARGO_BEGIN + "\n"
94
+ @ioh.write name + "\n"
95
+ @ioh.write digest + "\n"
96
+ @ioh.write b64_data + "\n"
97
+ @ioh.write CARGO_END + "\n"
98
+ end
99
+
100
+ # Returns a list of cargo section names available to be read
101
+ def cargo_section_names
102
+ return @cargo_locations.keys
103
+ end
104
+
105
+ # Returns true if cargo with a given name is available
106
+ def has_cargo_named?(name)
107
+ return @cargo_locations.has_key? name
108
+ end
109
+
110
+ # Reads, verifies, decodes, and returns the first cargo section with a given name
111
+ def first_cargo_section(name)
112
+ each_cargo_section(name) do |data|
113
+ return data
114
+ end
115
+ end
116
+
117
+ # Returns the first element from the return value of first_cargo_section
118
+ def first_cargo_element(name)
119
+ arr = first_cargo_section(name)
120
+ return (arr && arr.size > 0) ? arr[0] : nil
121
+ end
122
+
123
+ # Reads, verifies, and decodes each cargo section with a given name, passing each section's decoded data to the block
124
+ def each_cargo_section(name)
125
+ raise CargoStreamerError.new("Mode must be 'r' to read cargo data") unless @mode == "r"
126
+ locations = @cargo_locations[name] or return
127
+ locations.each do |seek_location|
128
+ @ioh.seek(seek_location)
129
+ digest = ""
130
+ encoded_data = ""
131
+ @ioh.each_line do |line|
132
+ line.chomp!
133
+ if line == CARGO_END
134
+ break
135
+ elsif digest == ""
136
+ digest = line
137
+ else
138
+ encoded_data += line
139
+ end
140
+ end
141
+
142
+ yield verify_and_decode_cargo(digest, encoded_data)
143
+ end
144
+ end
145
+
146
+ private
147
+
148
+ def scan_for_cargo
149
+ # Key is cargo section name as String, value is array of seek locations to digests for that section
150
+ @cargo_locations = {}
151
+ @ioh.rewind
152
+
153
+ in_cargo = false
154
+ found_name = false
155
+ @ioh.each_line do |line|
156
+ line.chomp!
157
+ if in_cargo
158
+ if line.include? CARGO_END
159
+ in_cargo = false
160
+ found_name = false
161
+ else
162
+ unless found_name
163
+ @cargo_locations[line] ||= []
164
+ @cargo_locations[line] << @ioh.tell
165
+ found_name = true
166
+ end
167
+ end
168
+ else
169
+ if line.include? CARGO_BEGIN
170
+ in_cargo = true
171
+ end
172
+ end
173
+ end
174
+ raise CargoStreamerError.new("Input contained un-terminated cargo section") unless in_cargo == false
175
+
176
+ @ioh.rewind
177
+ end
178
+
179
+ def clean_for_html_comment(s)
180
+ s.to_s.gsub("--", "__").gsub("<", "[").gsub(">", "]")
181
+ end
182
+
183
+ def compose_record_from_hash(model_class_name, attrs_hash)
184
+ model_class = model_class_name.constantize
185
+ raise "Class #{model_class_name} does not have cargo safety method" unless model_class.respond_to? :safe_to_load_from_cargo_stream?
186
+ raise "Class #{model_class_name} is not safe_to_load_from_cargo_stream" unless model_class.safe_to_load_from_cargo_stream?
187
+
188
+ rec = model_class.new
189
+ rec.send(:attributes=, attrs_hash, false) # No attr_accessible check like this, so all attributes can be set
190
+ rec.readonly! # rec is just source data for creation of a "real" record; it shouldn't be saveable itself
191
+ rec
192
+ end
193
+
194
+ def verify_and_decode_cargo(digest, b64_data)
195
+ deflated_data = Base64.decode64(b64_data)
196
+ raise "MD5 check failure" unless Digest::MD5::hexdigest(deflated_data) == digest
197
+
198
+ # Even though we encoded an Array with Array#to_xml, there is no Array#from_xml
199
+ # So, we have to use Hash#from_xml
200
+ records = Hash.from_xml(Zlib::Inflate::inflate(deflated_data))["records"]["record"]
201
+ raise "Decode failure, unable to find records key" unless records != nil
202
+ records = [records] unless records.is_a?(Array)
203
+ return records.map do |attrs_hash|
204
+ raise "Unable to find record type" unless attrs_hash.has_key?("cargo_streamer_type")
205
+ class_name = attrs_hash.delete("cargo_streamer_type")
206
+
207
+ raise "Unable to find includes list" unless attrs_hash.has_key?("cargo_streamer_includes")
208
+ (attrs_hash.delete("cargo_streamer_includes") || "").split(",").each do |assoc_info|
209
+ assoc_name, i_class_name = assoc_info.split("=")
210
+ attrs_hash[assoc_name] = compose_record_from_hash(i_class_name, attrs_hash[assoc_name])
211
+ end
212
+
213
+ compose_record_from_hash(class_name, attrs_hash)
214
+ end
215
+ rescue StandardError => e
216
+ raise CargoStreamerError.new("Corrupted data : #{e.class.to_s} : #{e.to_s}")
217
+ end
218
+
219
+ CARGO_BEGIN = "<!-- CARGO SEGMENT"
220
+ CARGO_END = "END CARGO SEGMENT -->"
221
+ end
222
+ end