+require 'stringio'
+
# The Potlatch module provides helper functions for potlatch and its communication with the server
module Potlatch
# Return two-byte integer
def self.getint(s)
- s.getc*256+s.getc
+ s.getbyte*256+s.getbyte
end
# Return four-byte long
def self.getlong(s)
- ((s.getc*256+s.getc)*256+s.getc)*256+s.getc
+ ((s.getbyte*256+s.getbyte)*256+s.getbyte)*256+s.getbyte
end
# Return string with two-byte length
def self.getstring(s)
- len=s.getc*256+s.getc
- s.read(len)
+ len=s.getbyte*256+s.getbyte
+ str=s.read(len)
+ str.force_encoding("UTF-8") if str.respond_to?("force_encoding")
+ str
end
# Return eight-byte double-precision float
if (key=='') then break end
arr[key]=getvalue(s)
end
- s.getc # skip the 9 'end of object' value
+ s.getbyte # skip the 9 'end of object' value
arr
end
# Parse and get value
def self.getvalue(s)
- case s.getc
+ case s.getbyte
when 0; return getdouble(s) # number
- when 1; return s.getc # boolean
+ when 1; return s.getbyte # boolean
when 2; return getstring(s) # string
when 3; return getobject(s) # object/hash
- when 5; return nil # null
- when 6; return nil # undefined
- when 8; s.read(4) # mixedArray
- return getobject(s) # |
- when 10;return getarray(s) # array
- else; return nil # error
+ when 5; return nil # null
+ when 6; return nil # undefined
+ when 8; s.read(4) # mixedArray
+ return getobject(s) # |
+ when 10; return getarray(s) # array
+ else; return nil # error
end
end
when 'Hash'
a=3.chr
n.each do |k,v|
- a+=encodestring(k)+encodevalue(v)
+ a+=encodestring(k.to_s)+encodevalue(v)
end
a+0.chr+0.chr+9.chr
when 'String'
0.chr+encodedouble(n)
when 'NilClass'
5.chr
+ when 'TrueClass'
+ 0.chr+encodedouble(1)
+ when 'FalseClass'
+ 0.chr+encodedouble(0)
else
- RAILS_DEFAULT_LOGGER.error("Unexpected Ruby type for AMF conversion: "+n.class.to_s)
+ Rails.logger.error("Unexpected Ruby type for AMF conversion: "+n.class.to_s)
end
end
# Encode string with two-byte length
- def self.encodestring(n)
+ def self.encodestring(n)
+ n=n.dup.force_encoding("ASCII-8BIT") if n.respond_to?("force_encoding")
a,b=n.size.divmod(256)
a.chr+b.chr+n
end
end
+ # The Dispatcher class handles decoding a series of RPC calls
+ # from the request, dispatching them, and encoding the response
+ class Dispatcher
+ def initialize(request, &block)
+ # Get stream for request data
+ @request = StringIO.new(request + 0.chr)
+
+ # Skip version indicator and client ID
+ @request.read(2)
+
+ # Skip headers
+ AMF.getint(@request).times do # Read number of headers and loop
+ AMF.getstring(@request) # | skip name
+ req.getbyte # | skip boolean
+ AMF.getvalue(@request) # | skip value
+ end
+
+ # Capture the dispatch routine
+ @dispatch = Proc.new
+ end
+
+ def each(&block)
+ # Read number of message bodies
+ bodies = AMF.getint(@request)
+
+ # Output response header
+ a,b = bodies.divmod(256)
+ yield 0.chr + 0.chr + 0.chr + 0.chr + a.chr + b.chr
+
+ # Process the bodies
+ bodies.times do # Read each body
+ name = AMF.getstring(@request) # | get message name
+ index = AMF.getstring(@request) # | get index in response sequence
+ bytes = AMF.getlong(@request) # | get total size in bytes
+ args = AMF.getvalue(@request) # | get response (probably an array)
+
+ result = @dispatch.call(name, *args)
+
+ yield AMF.putdata(index, result)
+ end
+ end
+ end
# The Potlatch class is a helper for Potlatch
class Potlatch
# [3] colours, [4] casing, [5] areas, [6] autotags
# (all hashes)
def self.get_presets
- RAILS_DEFAULT_LOGGER.info(" Message: getpresets")
+ Rails.logger.info(" Message: getpresets")
# Read preset menus
presets={}
presettype=''
presetcategory=''
# StringIO.open(txt) do |file|
- File.open("#{RAILS_ROOT}/config/potlatch/presets.txt") do |file|
+ File.open("#{Rails.root}/config/potlatch/presets.txt") do |file|
file.each_line {|line|
t=line.chomp
if (t=~/(\w+)\/(\w+)/) then
presetcategory=$2
presetmenus[presettype].push(presetcategory)
presetnames[presettype][presetcategory]=["(no preset)"]
- elsif (t=~/^(.+):\s?(.+)$/) then
+ elsif (t=~/^([\w\s]+):\s?(.+)$/) then
pre=$1; kv=$2
presetnames[presettype][presetcategory].push(pre)
presets[pre]={}
# Read colours/styling
colours={}; casing={}; areas={}
- File.open("#{RAILS_ROOT}/config/potlatch/colours.txt") do |file|
+ File.open("#{Rails.root}/config/potlatch/colours.txt") do |file|
file.each_line {|line|
t=line.chomp
if (t=~/(\w+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/) then
# Read relations colours/styling
relcolours={}; relalphas={}; relwidths={}
- File.open("#{RAILS_ROOT}/config/potlatch/relation_colours.txt") do |file|
+ File.open("#{Rails.root}/config/potlatch/relation_colours.txt") do |file|
file.each_line {|line|
t=line.chomp
if (t=~/(\w+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/) then
}
end
+ # Read POI presets
+ icon_list=[]; icon_tags={};
+ File.open("#{Rails.root}/config/potlatch/icon_presets.txt") do |file|
+ file.each_line {|line|
+ (icon,tags)=line.chomp.split("\t")
+ icon_list.push(icon)
+ icon_tags[icon]=Hash[*tags.scan(/([^;=]+)=([^;=]+)/).flatten]
+ }
+ end
+ icon_list.reverse!
+
# Read auto-complete
autotags={}; autotags['point']={}; autotags['way']={}; autotags['POI']={};
- File.open("#{RAILS_ROOT}/config/potlatch/autocomplete.txt") do |file|
+ File.open("#{Rails.root}/config/potlatch/autocomplete.txt") do |file|
file.each_line {|line|
t=line.chomp
- if (t=~/^(\w+)\/(\w+)\s+(.+)$/) then
+ if (t=~/^([\w:]+)\/(\w+)\s+(.+)$/) then
tag=$1; type=$2; values=$3
if values=='-' then autotags[type][tag]=[]
else autotags[type][tag]=values.split(',').sort.reverse end
}
end
- [presets,presetmenus,presetnames,colours,casing,areas,autotags,relcolours,relalphas,relwidths]
+ [presets,presetmenus,presetnames,colours,casing,areas,autotags,relcolours,relalphas,relwidths,icon_list,{},icon_tags]
end
end