taps 0.3.21 → 0.3.22.pre1

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.
@@ -32,7 +32,7 @@ or when you want to transfer tables that start with a word
32
32
 
33
33
  == Known Issues
34
34
 
35
- * Foreign Keys get lost in the schema transfer
35
+ * Foreign key constraints get lost in the schema transfer
36
36
  * Tables without primary keys will be incredibly slow to transfer. This is due to it being inefficient having large offset values in queries.
37
37
  * Multiple schemas are currently not supported
38
38
 
@@ -2,4 +2,4 @@
2
2
  :build:
3
3
  :major: 0
4
4
  :minor: 3
5
- :patch: 21
5
+ :patch: 22.pre1
@@ -3,7 +3,7 @@ require 'tempfile'
3
3
  require 'taps/monkey'
4
4
  require 'taps/config'
5
5
  require 'taps/log'
6
- require 'taps/json'
6
+ require 'vendor/okjson'
7
7
 
8
8
  Taps::Config.taps_database_url = ENV['TAPS_DATABASE_URL'] || begin
9
9
  # this is dirty but it solves a weird problem where the tempfile disappears mid-process
@@ -172,7 +172,7 @@ EOHELP
172
172
  end
173
173
 
174
174
  def clientresumexfer(method, opts)
175
- session = JSON.parse(File.read(opts.delete(:resume_filename)))
175
+ session = OkJson.parse(File.read(opts.delete(:resume_filename)))
176
176
  session.symbolize_recursively!
177
177
 
178
178
  database_url = opts.delete(:database_url)
@@ -3,7 +3,7 @@ require 'taps/multipart'
3
3
  require 'taps/utils'
4
4
  require 'taps/log'
5
5
  require 'taps/errors'
6
- require 'taps/json'
6
+ require 'vendor/okjson'
7
7
 
8
8
  module Taps
9
9
 
@@ -49,7 +49,7 @@ class DataStream
49
49
  end
50
50
 
51
51
  def to_json
52
- to_hash.to_json
52
+ OkJson.encode(to_hash)
53
53
  end
54
54
 
55
55
  def string_columns
@@ -167,20 +167,20 @@ class DataStream
167
167
  log.debug "DataStream#fetch_from_resource state -> #{state.inspect}"
168
168
  state[:chunksize] = Taps::Utils.calculate_chunksize(state[:chunksize]) do |c|
169
169
  state[:chunksize] = c.to_i
170
- res = resource.post({:state => self.to_json}, headers)
170
+ res = resource.post({:state => OkJson.encode(self)}, headers)
171
171
  end
172
172
 
173
173
  begin
174
174
  params = Taps::Multipart.parse(res)
175
175
  params[:json] = self.class.parse_json(params[:json]) if params.has_key?(:json)
176
176
  return params
177
- rescue JSON::Parser
178
- raise Taps::CorruptedData.new("Invalid JSON Received")
177
+ rescue OkJson::Parser
178
+ raise Taps::CorruptedData.new("Invalid OkJson Received")
179
179
  end
180
180
  end
181
181
 
182
182
  def self.parse_json(json)
183
- hash = JSON.parse(json).symbolize_keys
183
+ hash = OkJson.parse(json).symbolize_keys
184
184
  hash[:state].symbolize_keys! if hash.has_key?(:state)
185
185
  hash
186
186
  end
@@ -219,7 +219,7 @@ not enforce maximum values on integer types.
219
219
  end
220
220
 
221
221
  def verify_remote_stream(resource, headers)
222
- json_raw = resource.post({:state => self.to_json}, headers).to_s
222
+ json_raw = resource.post({:state => OkJson.encode(self)}, headers).to_s
223
223
  json = self.class.parse_json(json_raw)
224
224
 
225
225
  self.class.new(db, json[:state])
@@ -1,7 +1,7 @@
1
1
  require 'restclient'
2
2
  require 'rack/utils'
3
3
  require 'stringio'
4
- require 'taps/json'
4
+ require 'vendor/okjson'
5
5
 
6
6
  module Taps
7
7
  class Multipart
@@ -70,7 +70,7 @@ class Operation
70
70
  file = "#{file_prefix}_#{Time.now.strftime("%Y%m%d%H%M")}.dat"
71
71
  puts "\nSaving session to #{file}.."
72
72
  File.open(file, 'w') do |f|
73
- f.write(to_hash.to_json)
73
+ f.write(OkJson.encode(to_hash))
74
74
  end
75
75
  end
76
76
 
@@ -343,7 +343,7 @@ class Pull < Operation
343
343
  retries = 0
344
344
  max_retries = 10
345
345
  begin
346
- tables = JSON.parse(session_resource['pull/table_names'].get(http_headers).to_s)
346
+ tables = OkJson.decode(session_resource['pull/table_names'].get(http_headers).to_s)
347
347
  rescue RestClient::Exception
348
348
  retries += 1
349
349
  retry if retries <= max_retries
@@ -370,7 +370,7 @@ class Pull < Operation
370
370
  def pull_indexes
371
371
  puts "Receiving indexes"
372
372
 
373
- idxs = JSON.parse(session_resource['pull/indexes'].get(http_headers).to_s)
373
+ idxs = OkJson.decode(session_resource['pull/indexes'].get(http_headers).to_s)
374
374
 
375
375
  apply_table_filter(idxs).each do |table, indexes|
376
376
  next unless indexes.size > 0
@@ -416,7 +416,7 @@ class Push < Operation
416
416
  end
417
417
 
418
418
  def push_indexes
419
- idxs = JSON.parse(Taps::Utils.schema_bin(:indexes_individual, database_url))
419
+ idxs = OkJson.decode(Taps::Utils.schema_bin(:indexes_individual, database_url))
420
420
 
421
421
  return unless idxs.size > 0
422
422
 
@@ -512,7 +512,7 @@ class Push < Operation
512
512
  :payload => encoded_data,
513
513
  :content_type => 'application/octet-stream'
514
514
  r.attach :name => :json,
515
- :payload => data.to_json,
515
+ :payload => OkJson.encode(data),
516
516
  :content_type => 'application/json'
517
517
  end
518
518
  end
@@ -1,7 +1,7 @@
1
1
  require 'sequel'
2
2
  require 'sequel/extensions/schema_dumper'
3
3
  require 'sequel/extensions/migration'
4
- require 'taps/json'
4
+ require 'vendor/okjson'
5
5
 
6
6
  module Taps
7
7
  module Schema
@@ -54,7 +54,7 @@ end
54
54
  END_MIG
55
55
  end
56
56
  end
57
- idxs.to_json
57
+ OkJson.encode(idxs)
58
58
  end
59
59
 
60
60
  def load(database_url, schema)
@@ -26,7 +26,7 @@ class Server < Sinatra::Base
26
26
  end
27
27
  if e.kind_of?(Taps::BaseError)
28
28
  content_type "application/json"
29
- halt 412, { 'error_class' => e.class.to_s, 'error_message' => e.message, 'error_backtrace' => e.backtrace.join("\n") }.to_json
29
+ halt 412, OkJson.encode({ 'error_class' => e.class.to_s, 'error_message' => e.message, 'error_backtrace' => e.backtrace.join("\n") })
30
30
  else
31
31
  "Taps Server Error: #{e}\n#{e.backtrace}"
32
32
  end
@@ -73,7 +73,7 @@ class Server < Sinatra::Base
73
73
  end
74
74
 
75
75
  content_type 'application/json'
76
- { :state => stream.to_hash }.to_json
76
+ OkJson.encode({ :state => stream.to_hash })
77
77
  end
78
78
 
79
79
  post '/sessions/:key/push/table' do
@@ -142,7 +142,7 @@ class Server < Sinatra::Base
142
142
  end
143
143
 
144
144
  content_type 'application/json'
145
- tables.to_json
145
+ OkJson.encode(tables)
146
146
  end
147
147
 
148
148
  post '/sessions/:key/pull/table_count' do
@@ -164,13 +164,13 @@ class Server < Sinatra::Base
164
164
  stream = nil
165
165
 
166
166
  session.conn do |db|
167
- state = JSON.parse(params[:state]).symbolize_keys
167
+ state = OkJson.decode(params[:state]).symbolize_keys
168
168
  stream = Taps::DataStream.factory(db, state)
169
169
  encoded_data = stream.fetch.first
170
170
  end
171
171
 
172
172
  checksum = Taps::Utils.checksum(encoded_data).to_s
173
- json = { :checksum => checksum, :state => stream.to_hash }.to_json
173
+ json = OkJson.encode({ :checksum => checksum, :state => stream.to_hash })
174
174
 
175
175
  content, content_type_value = Taps::Multipart.create do |r|
176
176
  r.attach :name => :encoded_data,
@@ -171,7 +171,7 @@ Data : #{data}
171
171
  def reraise_server_exception(e)
172
172
  if e.kind_of?(RestClient::Exception)
173
173
  if e.respond_to?(:response) && e.response.headers[:content_type] == 'application/json'
174
- json = JSON.parse(e.response.to_s)
174
+ json = OkJson.decode(e.response.to_s)
175
175
  klass = eval(json['error_class']) rescue nil
176
176
  raise klass.new(json['error_message'], :backtrace => json['error_backtrace']) if klass
177
177
  end
@@ -0,0 +1,556 @@
1
+ # Copyright 2011 Keith Rarick
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ # See https://github.com/kr/okjson for updates.
22
+
23
+ require 'stringio'
24
+
25
+ # Some parts adapted from
26
+ # http://golang.org/src/pkg/json/decode.go and
27
+ # http://golang.org/src/pkg/utf8/utf8.go
28
+ module OkJson
29
+ extend self
30
+
31
+ class ParserError < ::StandardError; end
32
+
33
+ # Decodes a json document in string s and
34
+ # returns the corresponding ruby value.
35
+ # String s must be valid UTF-8. If you have
36
+ # a string in some other encoding, convert
37
+ # it first.
38
+ #
39
+ # String values in the resulting structure
40
+ # will be UTF-8.
41
+ def decode(s)
42
+ ts = lex(s)
43
+ v, ts = textparse(ts)
44
+ if ts.length > 0
45
+ raise OkJson::ParserError, 'trailing garbage'
46
+ end
47
+ v
48
+ end
49
+
50
+
51
+ # Parses a "json text" in the sense of RFC 4627.
52
+ # Returns the parsed value and any trailing tokens.
53
+ # Note: this is almost the same as valparse,
54
+ # except that it does not accept atomic values.
55
+ def textparse(ts)
56
+ if ts.length < 0
57
+ raise OkJson::ParserError, 'empty'
58
+ end
59
+
60
+ typ, _, val = ts[0]
61
+ case typ
62
+ when '{' then objparse(ts)
63
+ when '[' then arrparse(ts)
64
+ else
65
+ raise OkJson::ParserError, "unexpected #{val.inspect}"
66
+ end
67
+ end
68
+
69
+
70
+ # Parses a "value" in the sense of RFC 4627.
71
+ # Returns the parsed value and any trailing tokens.
72
+ def valparse(ts)
73
+ if ts.length < 0
74
+ raise OkJson::ParserError, 'empty'
75
+ end
76
+
77
+ typ, _, val = ts[0]
78
+ case typ
79
+ when '{' then objparse(ts)
80
+ when '[' then arrparse(ts)
81
+ when :val,:str then [val, ts[1..-1]]
82
+ else
83
+ raise OkJson::ParserError, "unexpected #{val.inspect}"
84
+ end
85
+ end
86
+
87
+
88
+ # Parses an "object" in the sense of RFC 4627.
89
+ # Returns the parsed value and any trailing tokens.
90
+ def objparse(ts)
91
+ ts = eat('{', ts)
92
+ obj = {}
93
+
94
+ if ts[0][0] == '}'
95
+ return obj, ts[1..-1]
96
+ end
97
+
98
+ k, v, ts = pairparse(ts)
99
+ obj[k] = v
100
+
101
+ if ts[0][0] == '}'
102
+ return obj, ts[1..-1]
103
+ end
104
+
105
+ loop do
106
+ ts = eat(',', ts)
107
+
108
+ k, v, ts = pairparse(ts)
109
+ obj[k] = v
110
+
111
+ if ts[0][0] == '}'
112
+ return obj, ts[1..-1]
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+ # Parses a "member" in the sense of RFC 4627.
119
+ # Returns the parsed value and any trailing tokens.
120
+ def pairparse(ts)
121
+ (typ, _, k), ts = ts[0], ts[1..-1]
122
+ if typ != :str
123
+ raise OkJson::ParserError, "unexpected #{k.inspect}"
124
+ end
125
+ ts = eat(':', ts)
126
+ v, ts = valparse(ts)
127
+ [k, v, ts]
128
+ end
129
+
130
+
131
+ # Parses an "array" in the sense of RFC 4627.
132
+ # Returns the parsed value and any trailing tokens.
133
+ def arrparse(ts)
134
+ ts = eat('[', ts)
135
+ arr = []
136
+
137
+ if ts[0][0] == ']'
138
+ return arr, ts[1..-1]
139
+ end
140
+
141
+ v, ts = valparse(ts)
142
+ arr << v
143
+
144
+ if ts[0][0] == ']'
145
+ return arr, ts[1..-1]
146
+ end
147
+
148
+ loop do
149
+ ts = eat(',', ts)
150
+
151
+ v, ts = valparse(ts)
152
+ arr << v
153
+
154
+ if ts[0][0] == ']'
155
+ return arr, ts[1..-1]
156
+ end
157
+ end
158
+ end
159
+
160
+
161
+ def eat(typ, ts)
162
+ if ts[0][0] != typ
163
+ raise OkJson::ParserError, "expected #{typ} (got #{ts[0].inspect})"
164
+ end
165
+ ts[1..-1]
166
+ end
167
+
168
+
169
+ # Sans s and returns a list of json tokens,
170
+ # excluding white space (as defined in RFC 4627).
171
+ def lex(s)
172
+ ts = []
173
+ while s.length > 0
174
+ typ, lexeme, val = tok(s)
175
+ if typ == nil
176
+ raise OkJson::ParserError, "invalid character at #{s[0,10].inspect}"
177
+ end
178
+ if typ != :space
179
+ ts << [typ, lexeme, val]
180
+ end
181
+ s = s[lexeme.length..-1]
182
+ end
183
+ ts
184
+ end
185
+
186
+
187
+ # Scans the first token in s and
188
+ # returns a 3-element list, or nil
189
+ # if no such token exists.
190
+ #
191
+ # The first list element is one of
192
+ # '{', '}', ':', ',', '[', ']',
193
+ # :val, :str, and :space.
194
+ #
195
+ # The second element is the lexeme.
196
+ #
197
+ # The third element is the value of the
198
+ # token for :val and :str, otherwise
199
+ # it is the lexeme.
200
+ def tok(s)
201
+ case s[0]
202
+ when ?{ then ['{', s[0,1], s[0,1]]
203
+ when ?} then ['}', s[0,1], s[0,1]]
204
+ when ?: then [':', s[0,1], s[0,1]]
205
+ when ?, then [',', s[0,1], s[0,1]]
206
+ when ?[ then ['[', s[0,1], s[0,1]]
207
+ when ?] then [']', s[0,1], s[0,1]]
208
+ when ?n then nulltok(s)
209
+ when ?t then truetok(s)
210
+ when ?f then falsetok(s)
211
+ when ?" then strtok(s)
212
+ when Spc then [:space, s[0,1], s[0,1]]
213
+ when ?\t then [:space, s[0,1], s[0,1]]
214
+ when ?\n then [:space, s[0,1], s[0,1]]
215
+ when ?\r then [:space, s[0,1], s[0,1]]
216
+ else numtok(s)
217
+ end
218
+ end
219
+
220
+
221
+ def nulltok(s); s[0,4] == 'null' && [:val, 'null', nil] end
222
+ def truetok(s); s[0,4] == 'true' && [:val, 'true', true] end
223
+ def falsetok(s); s[0,5] == 'false' && [:val, 'false', false] end
224
+
225
+
226
+ def numtok(s)
227
+ m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
228
+ if m && m.begin(0) == 0
229
+ if m[3] && !m[2]
230
+ [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
231
+ elsif m[2]
232
+ [:val, m[0], Float(m[0])]
233
+ else
234
+ [:val, m[0], Integer(m[0])]
235
+ end
236
+ end
237
+ end
238
+
239
+
240
+ def strtok(s)
241
+ m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
242
+ if ! m
243
+ raise OkJson::ParserError, "invalid string literal at #{abbrev(s)}"
244
+ end
245
+ [:str, m[0], unquote(m[0])]
246
+ end
247
+
248
+
249
+ def abbrev(s)
250
+ t = s[0,10]
251
+ p = t['`']
252
+ t = t[0,p] if p
253
+ t = t + '...' if t.length < s.length
254
+ '`' + t + '`'
255
+ end
256
+
257
+
258
+ # Converts a quoted json string literal q into a UTF-8-encoded string.
259
+ # The rules are different than for Ruby, so we cannot use eval.
260
+ # Unquote will raise OkJson::ParserError, an error if q contains control characters.
261
+ def unquote(q)
262
+ q = q[1...-1]
263
+ a = q.dup # allocate a big enough string
264
+ r, w = 0, 0
265
+ while r < q.length
266
+ c = q[r]
267
+ case true
268
+ when c == ?\\
269
+ r += 1
270
+ if r >= q.length
271
+ raise OkJson::ParserError, "string literal ends with a \"\\\": \"#{q}\""
272
+ end
273
+
274
+ case q[r]
275
+ when ?",?\\,?/,?'
276
+ a[w] = q[r]
277
+ r += 1
278
+ w += 1
279
+ when ?b,?f,?n,?r,?t
280
+ a[w] = Unesc[q[r]]
281
+ r += 1
282
+ w += 1
283
+ when ?u
284
+ r += 1
285
+ uchar = begin
286
+ hexdec4(q[r,4])
287
+ rescue RuntimeError => e
288
+ raise OkJson::ParserError, "invalid escape sequence \\u#{q[r,4]}: #{e}"
289
+ end
290
+ r += 4
291
+ if surrogate? uchar
292
+ if q.length >= r+6
293
+ uchar1 = hexdec4(q[r+2,4])
294
+ uchar = subst(uchar, uchar1)
295
+ if uchar != Ucharerr
296
+ # A valid pair; consume.
297
+ r += 6
298
+ end
299
+ end
300
+ end
301
+ w += ucharenc(a, w, uchar)
302
+ else
303
+ raise OkJson::ParserError, "invalid escape char #{q[r]} in \"#{q}\""
304
+ end
305
+ when c == ?", c < Spc
306
+ raise OkJson::ParserError, "invalid character in string literal \"#{q}\""
307
+ else
308
+ # Copy anything else byte-for-byte.
309
+ # Valid UTF-8 will remain valid UTF-8.
310
+ # Invalid UTF-8 will remain invalid UTF-8.
311
+ a[w] = c
312
+ r += 1
313
+ w += 1
314
+ end
315
+ end
316
+ a[0,w]
317
+ end
318
+
319
+
320
+ def hexdec4(s)
321
+ if s.length != 4
322
+ raise OkJson::ParserError, 'short'
323
+ end
324
+ (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
325
+ end
326
+
327
+
328
+ def subst(u1, u2)
329
+ if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
330
+ return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
331
+ end
332
+ return Ucharerr
333
+ end
334
+
335
+
336
+ def unsubst(u)
337
+ if u < Usurrself || u > Umax || surrogate?(u)
338
+ return Ucharerr, Ucharerr
339
+ end
340
+ u -= Usurrself
341
+ [Usurr1 + ((u>>10)&0x3ff), Usurr2 + (u&0x3ff)]
342
+ end
343
+
344
+
345
+ def surrogate?(u)
346
+ Usurr1 <= u && u < Usurr3
347
+ end
348
+
349
+
350
+ def nibble(c)
351
+ case true
352
+ when ?0 <= c && c <= ?9 then c.ord - ?0.ord
353
+ when ?a <= c && c <= ?z then c.ord - ?a.ord + 10
354
+ when ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
355
+ else
356
+ raise OkJson::ParserError, "invalid hex code #{c}"
357
+ end
358
+ end
359
+
360
+
361
+ # Encodes x into a json text. It may contain only
362
+ # Array, Hash, String, Numeric, true, false, nil.
363
+ # (Note, this list excludes Symbol.)
364
+ # Strings contained in x must be valid UTF-8.
365
+ # Values that cannot be represented, such as
366
+ # Nan, Infinity, Symbol, and Proc, are encoded
367
+ # as null, in accordance with ECMA-262, 5th ed.
368
+ def encode(x)
369
+ case x
370
+ when Hash then objenc(x)
371
+ when Array then arrenc(x)
372
+ when String then strenc(x)
373
+ when Numeric then numenc(x)
374
+ when Symbol then strenc(x.to_s)
375
+ when true then "true"
376
+ when false then "false"
377
+ when nil then "null"
378
+ else "null"
379
+ end
380
+ end
381
+
382
+
383
+ def objenc(x)
384
+ '{' + x.map{|k,v| encode(k) + ':' + encode(v)}.join(',') + '}'
385
+ end
386
+
387
+
388
+ def arrenc(a)
389
+ '[' + a.map{|x| encode(x)}.join(',') + ']'
390
+ end
391
+
392
+
393
+ def strenc(s)
394
+ t = StringIO.new
395
+ t.putc(?")
396
+ r = 0
397
+ while r < s.length
398
+ case s[r]
399
+ when ?" then t.print('\\"')
400
+ when ?\\ then t.print('\\\\')
401
+ when ?\b then t.print('\\b')
402
+ when ?\f then t.print('\\f')
403
+ when ?\n then t.print('\\n')
404
+ when ?\r then t.print('\\r')
405
+ when ?\t then t.print('\\t')
406
+ else
407
+ c = s[r]
408
+ case true
409
+ when Spc <= c && c <= ?~
410
+ t.putc(c)
411
+ when true
412
+ u, size = uchardec(s, r)
413
+ r += size - 1 # we add one more at the bottom of the loop
414
+ if u < 0x10000
415
+ t.print('\\u')
416
+ hexenc4(t, u)
417
+ else
418
+ u1, u2 = unsubst(u)
419
+ t.print('\\u')
420
+ hexenc4(t, u1)
421
+ t.print('\\u')
422
+ hexenc4(t, u2)
423
+ end
424
+ else
425
+ # invalid byte; skip it
426
+ end
427
+ end
428
+ r += 1
429
+ end
430
+ t.putc(?")
431
+ t.string
432
+ end
433
+
434
+
435
+ def hexenc4(t, u)
436
+ t.putc(Hex[(u>>12)&0xf])
437
+ t.putc(Hex[(u>>8)&0xf])
438
+ t.putc(Hex[(u>>4)&0xf])
439
+ t.putc(Hex[u&0xf])
440
+ end
441
+
442
+
443
+ def numenc(x)
444
+ if x.nan? || x.infinite?
445
+ return 'null'
446
+ end rescue nil
447
+ "#{x}"
448
+ end
449
+
450
+
451
+ # Decodes unicode character u from UTF-8
452
+ # bytes in string s at position i.
453
+ # Returns u and the number of bytes read.
454
+ def uchardec(s, i)
455
+ n = s.length - i
456
+ return [Ucharerr, 1] if n < 1
457
+
458
+ c0 = s[i].ord
459
+
460
+ # 1-byte, 7-bit sequence?
461
+ if c0 < Utagx
462
+ return [c0, 1]
463
+ end
464
+
465
+ # unexpected continuation byte?
466
+ return [Ucharerr, 1] if c0 < Utag2
467
+
468
+ # need continuation byte
469
+ return [Ucharerr, 1] if n < 2
470
+ c1 = s[i+1].ord
471
+ return [Ucharerr, 1] if c1 < Utagx || Utag2 <= c1
472
+
473
+ # 2-byte, 11-bit sequence?
474
+ if c0 < Utag3
475
+ u = (c0&Umask2)<<6 | (c1&Umaskx)
476
+ return [Ucharerr, 1] if u <= Uchar1max
477
+ return [u, 2]
478
+ end
479
+
480
+ # need second continuation byte
481
+ return [Ucharerr, 1] if n < 3
482
+ c2 = s[i+2].ord
483
+ return [Ucharerr, 1] if c2 < Utagx || Utag2 <= c2
484
+
485
+ # 3-byte, 16-bit sequence?
486
+ if c0 < Utag4
487
+ u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
488
+ return [Ucharerr, 1] if u <= Uchar2max
489
+ return [u, 3]
490
+ end
491
+
492
+ # need third continuation byte
493
+ return [Ucharerr, 1] if n < 4
494
+ c3 = s[i+3].ord
495
+ return [Ucharerr, 1] if c3 < Utagx || Utag2 <= c3
496
+
497
+ # 4-byte, 21-bit sequence?
498
+ if c0 < Utag5
499
+ u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
500
+ return [Ucharerr, 1] if u <= Uchar3max
501
+ return [u, 4]
502
+ end
503
+
504
+ return [Ucharerr, 1]
505
+ end
506
+
507
+
508
+ # Encodes unicode character u as UTF-8
509
+ # bytes in string a at position i.
510
+ # Returns the number of bytes written.
511
+ def ucharenc(a, i, u)
512
+ case true
513
+ when u <= Uchar1max
514
+ a[i] = (u & 0xff).chr
515
+ 1
516
+ when u <= Uchar2max
517
+ a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
518
+ a[i+1] = (Utagx | (u&Umaskx)).chr
519
+ 2
520
+ when u <= Uchar3max
521
+ a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
522
+ a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
523
+ a[i+2] = (Utagx | (u&Umaskx)).chr
524
+ 3
525
+ else
526
+ a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
527
+ a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
528
+ a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
529
+ a[i+3] = (Utagx | (u&Umaskx)).chr
530
+ 4
531
+ end
532
+ end
533
+
534
+ Utagx = 0x80 # 1000 0000
535
+ Utag2 = 0xc0 # 1100 0000
536
+ Utag3 = 0xe0 # 1110 0000
537
+ Utag4 = 0xf0 # 1111 0000
538
+ Utag5 = 0xF8 # 1111 1000
539
+ Umaskx = 0x3f # 0011 1111
540
+ Umask2 = 0x1f # 0001 1111
541
+ Umask3 = 0x0f # 0000 1111
542
+ Umask4 = 0x07 # 0000 0111
543
+ Uchar1max = (1<<7) - 1
544
+ Uchar2max = (1<<11) - 1
545
+ Uchar3max = (1<<16) - 1
546
+ Ucharerr = 0xFFFD # unicode "replacement char"
547
+ Usurrself = 0x10000
548
+ Usurr1 = 0xd800
549
+ Usurr2 = 0xdc00
550
+ Usurr3 = 0xe000
551
+ Umax = 0x10ffff
552
+
553
+ Spc = ' '[0]
554
+ Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
555
+ Hex = '0123456789abcdef'
556
+ end
@@ -23,7 +23,7 @@ describe Taps::Server do
23
23
  end
24
24
 
25
25
  it "verifies the client taps version" do
26
- get('/', { }, { 'HTTP_AUTHORIZATION' => @auth_header, 'HTTP_TAPS_VERSION' => Taps.compatible_version + ".14" })
26
+ get('/', { }, { 'HTTP_AUTHORIZATION' => @auth_header, 'HTTP_TAPS_VERSION' => Taps.version })
27
27
  last_response.status.should == 200
28
28
  end
29
29
 
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taps
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.3.21
4
+ prerelease: 7
5
+ version: 0.3.22.pre1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ricardo Chimal, Jr.
@@ -10,35 +10,24 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-25 00:00:00 -04:00
13
+ date: 2011-04-01 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
- - !ruby/object:Gem::Dependency
17
- name: activesupport
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
20
- none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: 2.1.0
25
- type: :runtime
26
- version_requirements: *id001
27
16
  - !ruby/object:Gem::Dependency
28
17
  name: rack
29
18
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
19
+ requirement: &id001 !ruby/object:Gem::Requirement
31
20
  none: false
32
21
  requirements:
33
22
  - - ">="
34
23
  - !ruby/object:Gem::Version
35
24
  version: 1.0.1
36
25
  type: :runtime
37
- version_requirements: *id002
26
+ version_requirements: *id001
38
27
  - !ruby/object:Gem::Dependency
39
28
  name: rest-client
40
29
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
30
+ requirement: &id002 !ruby/object:Gem::Requirement
42
31
  none: false
43
32
  requirements:
44
33
  - - ">="
@@ -48,95 +37,95 @@ dependencies:
48
37
  - !ruby/object:Gem::Version
49
38
  version: 1.7.0
50
39
  type: :runtime
51
- version_requirements: *id003
40
+ version_requirements: *id002
52
41
  - !ruby/object:Gem::Dependency
53
42
  name: sequel
54
43
  prerelease: false
55
- requirement: &id004 !ruby/object:Gem::Requirement
44
+ requirement: &id003 !ruby/object:Gem::Requirement
56
45
  none: false
57
46
  requirements:
58
47
  - - ~>
59
48
  - !ruby/object:Gem::Version
60
49
  version: 3.20.0
61
50
  type: :runtime
62
- version_requirements: *id004
51
+ version_requirements: *id003
63
52
  - !ruby/object:Gem::Dependency
64
53
  name: sinatra
65
54
  prerelease: false
66
- requirement: &id005 !ruby/object:Gem::Requirement
55
+ requirement: &id004 !ruby/object:Gem::Requirement
67
56
  none: false
68
57
  requirements:
69
58
  - - ~>
70
59
  - !ruby/object:Gem::Version
71
60
  version: 1.0.0
72
61
  type: :runtime
73
- version_requirements: *id005
62
+ version_requirements: *id004
74
63
  - !ruby/object:Gem::Dependency
75
64
  name: sqlite3-ruby
76
65
  prerelease: false
77
- requirement: &id006 !ruby/object:Gem::Requirement
66
+ requirement: &id005 !ruby/object:Gem::Requirement
78
67
  none: false
79
68
  requirements:
80
69
  - - ~>
81
70
  - !ruby/object:Gem::Version
82
71
  version: "1.2"
83
72
  type: :runtime
84
- version_requirements: *id006
73
+ version_requirements: *id005
85
74
  - !ruby/object:Gem::Dependency
86
75
  name: bacon
87
76
  prerelease: false
88
- requirement: &id007 !ruby/object:Gem::Requirement
77
+ requirement: &id006 !ruby/object:Gem::Requirement
89
78
  none: false
90
79
  requirements:
91
80
  - - ">="
92
81
  - !ruby/object:Gem::Version
93
82
  version: "0"
94
83
  type: :development
95
- version_requirements: *id007
84
+ version_requirements: *id006
96
85
  - !ruby/object:Gem::Dependency
97
86
  name: mocha
98
87
  prerelease: false
99
- requirement: &id008 !ruby/object:Gem::Requirement
88
+ requirement: &id007 !ruby/object:Gem::Requirement
100
89
  none: false
101
90
  requirements:
102
91
  - - ">="
103
92
  - !ruby/object:Gem::Version
104
93
  version: "0"
105
94
  type: :development
106
- version_requirements: *id008
95
+ version_requirements: *id007
107
96
  - !ruby/object:Gem::Dependency
108
97
  name: rack-test
109
98
  prerelease: false
110
- requirement: &id009 !ruby/object:Gem::Requirement
99
+ requirement: &id008 !ruby/object:Gem::Requirement
111
100
  none: false
112
101
  requirements:
113
102
  - - ">="
114
103
  - !ruby/object:Gem::Version
115
104
  version: "0"
116
105
  type: :development
117
- version_requirements: *id009
106
+ version_requirements: *id008
118
107
  - !ruby/object:Gem::Dependency
119
108
  name: rake
120
109
  prerelease: false
121
- requirement: &id010 !ruby/object:Gem::Requirement
110
+ requirement: &id009 !ruby/object:Gem::Requirement
122
111
  none: false
123
112
  requirements:
124
113
  - - ">="
125
114
  - !ruby/object:Gem::Version
126
115
  version: "0"
127
116
  type: :development
128
- version_requirements: *id010
117
+ version_requirements: *id009
129
118
  - !ruby/object:Gem::Dependency
130
119
  name: rcov
131
120
  prerelease: false
132
- requirement: &id011 !ruby/object:Gem::Requirement
121
+ requirement: &id010 !ruby/object:Gem::Requirement
133
122
  none: false
134
123
  requirements:
135
124
  - - ">="
136
125
  - !ruby/object:Gem::Version
137
126
  version: "0"
138
127
  type: :development
139
- version_requirements: *id011
128
+ version_requirements: *id010
140
129
  description: A simple database agnostic import/export app to transfer data to/from a remote database.
141
130
  email: ricardo@heroku.com
142
131
  executables:
@@ -156,7 +145,6 @@ files:
156
145
  - lib/taps/data_stream.rb
157
146
  - lib/taps/db_session.rb
158
147
  - lib/taps/errors.rb
159
- - lib/taps/json.rb
160
148
  - lib/taps/log.rb
161
149
  - lib/taps/monkey.rb
162
150
  - lib/taps/multipart.rb
@@ -166,6 +154,7 @@ files:
166
154
  - lib/taps/server.rb
167
155
  - lib/taps/utils.rb
168
156
  - lib/taps/version.rb
157
+ - lib/vendor/okjson.rb
169
158
  - README.rdoc
170
159
  - spec/base.rb
171
160
  - spec/chunksize_spec.rb
@@ -193,9 +182,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
182
  required_rubygems_version: !ruby/object:Gem::Requirement
194
183
  none: false
195
184
  requirements:
196
- - - ">="
185
+ - - ">"
197
186
  - !ruby/object:Gem::Version
198
- version: "0"
187
+ version: 1.3.1
199
188
  requirements: []
200
189
 
201
190
  rubyforge_project:
@@ -1,13 +0,0 @@
1
- require "active_support"
2
- require "active_support/json"
3
- require "active_support/ordered_hash"
4
-
5
- # for compatibility with activesupport 2.2 and below
6
- unless Kernel.const_defined?(:JSON)
7
- module JSON
8
- def self.parse(json)
9
- ActiveSupport::JSON.decode(json)
10
- end
11
- end
12
- end
13
-