motion-csv 0.0.1 → 0.0.2
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.
- checksums.yaml +9 -9
- data/README.md +46 -1
- data/lib/motion-csv/motion-csv.rb +34 -0
- data/lib/motion-csv/stringio.rb +855 -0
- data/lib/motion-csv/version.rb +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDc0ZWE1OGExNjUxYjA1YTE1MjBhNGNiYjc3ZDAzZTMzZDAzYTc2MQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
7
|
-
|
6
|
+
NGRjMDlhOTljMzdiMzM0MDZkNTIxNThkNzc0NDIxMGU1ZjAyNGQ4NQ==
|
7
|
+
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTM1MWNmODVjMzUzZGFiMjY0M2Q5OWUyOTUyYjE4ZTk4MGNkN2JkOTM5MDk0
|
10
|
+
Zjg3MmFlODA4OTNkYmQwMTNiYWNjM2M3YmZjNThkNTJiOTRlMDY5ZWQ0NmI1
|
11
|
+
OWViYmRkNzg0NzUyNzFiMGJmZDFmNGZmMjJlNThhNmZlZmQxN2M=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZTU5N2MzM2ZiZjg5ZmJiMDA4OWExMTBmNGY3ZDhlNjhhN2U5N2U0MjJlYzYx
|
14
|
+
ZjMwMTE0ODMxMWIzMWQ0MTUxNDFjZWEyN2NjODViYzhjNmIwYjUwZjI0YWFh
|
15
|
+
OGY5M2I3ZmNiODE0N2MzOGE0YmYxMzY3ZjNhYmMyODg4ODFkOTg=
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# motion-csv
|
2
2
|
|
3
|
+
[](https://travis-ci.org/[markrickert/motion-csv) [](https://codeclimate.com/github/markrickert/motion-csv)
|
4
|
+
|
3
5
|
This is a RubyMotion friendly port of fasterer-csv by Mason: http://rubygems.org/gems/fasterer-csv
|
4
6
|
|
5
7
|
## Installation
|
@@ -18,7 +20,9 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
## Usage
|
20
22
|
|
21
|
-
Check out the `specs`
|
23
|
+
Check out the `specs` directory for usage examples, but here's a brief example:
|
24
|
+
|
25
|
+
### Standard Usage
|
22
26
|
|
23
27
|
```ruby
|
24
28
|
csv_string = "a,b,c,d
|
@@ -32,6 +36,44 @@ puts csv.first[:b] # 2
|
|
32
36
|
puts csv.last[:d] # "whatever"
|
33
37
|
```
|
34
38
|
|
39
|
+
### Generating a CSV String
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
MotionCSV.generate do |csv|
|
43
|
+
csv << ["row", "of", "CSV", "data"]
|
44
|
+
csv << ["another", "row"]
|
45
|
+
end
|
46
|
+
# "row,of,CSV,data\nanother,row\n"
|
47
|
+
```
|
48
|
+
|
49
|
+
### Convert an Array to CSV
|
50
|
+
This uses a convenience method on the `Array` class. You can pass it a single or two-dimensional array.
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
["testing", "arrays"].to_csv
|
54
|
+
# "testing,arrays\n"
|
55
|
+
```
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
[
|
59
|
+
['array1', 'stuff'],
|
60
|
+
['array2', 'more stuff']
|
61
|
+
].to_csv
|
62
|
+
# "array1,stuff\narray2,more stuff\n"
|
63
|
+
```
|
64
|
+
|
65
|
+
### Parse a String
|
66
|
+
This uses a convenience method on the `String` class.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
"header1,header2\nCSV,String".parse_csv
|
70
|
+
# [["CSV", "String"]]
|
71
|
+
```
|
72
|
+
|
73
|
+
## Tests
|
74
|
+
|
75
|
+
To run the testing suite, run `rake spec`.
|
76
|
+
|
35
77
|
## Contributing
|
36
78
|
|
37
79
|
1. Fork it
|
@@ -39,3 +81,6 @@ puts csv.last[:d] # "whatever"
|
|
39
81
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
82
|
4. Push to the branch (`git push origin my-new-feature`)
|
41
83
|
5. Create new Pull Request
|
84
|
+
|
85
|
+
---
|
86
|
+
[](https://bitdeli.com/free "Bitdeli Badge")
|
@@ -425,3 +425,37 @@ module MotionCSV
|
|
425
425
|
|
426
426
|
end
|
427
427
|
end
|
428
|
+
|
429
|
+
class Array
|
430
|
+
|
431
|
+
def to_csv
|
432
|
+
MotionCSV.generate do |csv|
|
433
|
+
if self.depth == 2
|
434
|
+
self.each do |a|
|
435
|
+
csv << a
|
436
|
+
end
|
437
|
+
else
|
438
|
+
csv << self
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
def depth
|
444
|
+
# Thanks, StackOverflow! http://stackoverflow.com/a/10863610/814123
|
445
|
+
b, depth = self.dup, 1
|
446
|
+
until b==self.flatten
|
447
|
+
depth+=1
|
448
|
+
b=b.flatten(1)
|
449
|
+
end
|
450
|
+
depth
|
451
|
+
end
|
452
|
+
|
453
|
+
end
|
454
|
+
|
455
|
+
class String
|
456
|
+
|
457
|
+
def parse_csv
|
458
|
+
MotionCSV.parse(self)
|
459
|
+
end
|
460
|
+
|
461
|
+
end
|
@@ -0,0 +1,855 @@
|
|
1
|
+
# MacRuby implementation of stringio.
|
2
|
+
#
|
3
|
+
# This file is covered by the Ruby license. See COPYING for more details.
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012, The MacRuby Team. All rights reserved.
|
6
|
+
# Copyright (C) 2009-2011, Apple Inc. All rights reserved.
|
7
|
+
|
8
|
+
class StringIO
|
9
|
+
|
10
|
+
attr_reader :string, :pos
|
11
|
+
|
12
|
+
# strio.lineno -> integer
|
13
|
+
#
|
14
|
+
# Returns the current line number in *strio*. The stringio must be
|
15
|
+
# opened for reading. +lineno+ counts the number of times +gets+ is
|
16
|
+
# called, rather than the number of newlines encountered. The two
|
17
|
+
# values will differ if +gets+ is called with a separator other than
|
18
|
+
# newline. See also the <code>$.</code> variable.
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# strio.lineno = integer -> integer
|
22
|
+
#
|
23
|
+
# Manually sets the current line number to the given value.
|
24
|
+
# <code>$.</code> is updated only on the next read.
|
25
|
+
#
|
26
|
+
attr_accessor :lineno
|
27
|
+
|
28
|
+
include Enumerable
|
29
|
+
|
30
|
+
# StringIO.open(string=""[, mode]) {|strio| ...}
|
31
|
+
#
|
32
|
+
# Equivalent to StringIO.new except that when it is called with a block, it
|
33
|
+
# yields with the new instance and closes it, and returns the result which
|
34
|
+
# returned from the block.
|
35
|
+
#
|
36
|
+
def self.open(*args)
|
37
|
+
obj = new(*args)
|
38
|
+
|
39
|
+
if block_given?
|
40
|
+
begin
|
41
|
+
yield obj
|
42
|
+
ensure
|
43
|
+
obj.close
|
44
|
+
obj.instance_variable_set(:@string, nil)
|
45
|
+
obj
|
46
|
+
end
|
47
|
+
else
|
48
|
+
obj
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# StringIO.new(string=""[, mode])
|
53
|
+
#
|
54
|
+
# Creates new StringIO instance from with _string_ and _mode_.
|
55
|
+
#
|
56
|
+
def initialize(string = String.new, mode = nil)
|
57
|
+
@string = string.to_str
|
58
|
+
@pos = 0
|
59
|
+
@lineno = 0
|
60
|
+
define_mode(mode)
|
61
|
+
|
62
|
+
raise Errno::EACCES if (@writable && string.frozen?)
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize_copy(from)
|
67
|
+
from = from.to_strio
|
68
|
+
self.taint if from.tainted?
|
69
|
+
|
70
|
+
@string = from.instance_variable_get(:@string).dup
|
71
|
+
# mode
|
72
|
+
@append = from.instance_variable_get(:@append)
|
73
|
+
@readable = from.instance_variable_get(:@readable)
|
74
|
+
@writable = from.instance_variable_get(:@writable)
|
75
|
+
|
76
|
+
@pos = from.instance_variable_get(:@pos)
|
77
|
+
@lineno = from.instance_variable_get(:@lineno)
|
78
|
+
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
# strio.reopen(other_StrIO) -> strio
|
83
|
+
# strio.reopen(string, mode) -> strio
|
84
|
+
#
|
85
|
+
# Reinitializes *strio* with the given <i>other_StrIO</i> or _string_
|
86
|
+
# and _mode_ (see StringIO#new).
|
87
|
+
#
|
88
|
+
def reopen(str=nil, mode=nil)
|
89
|
+
if str == nil && mode == nil
|
90
|
+
mode = 'w+'
|
91
|
+
elsif !str.kind_of?(String) && mode == nil
|
92
|
+
raise TypeError unless str.respond_to?(:to_strio)
|
93
|
+
return initialize_copy(str)
|
94
|
+
else
|
95
|
+
raise TypeError unless str.respond_to?(:to_str)
|
96
|
+
@string = str.to_str
|
97
|
+
end
|
98
|
+
|
99
|
+
define_mode(mode)
|
100
|
+
@pos = 0
|
101
|
+
@lineno = 0
|
102
|
+
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
# strio.string = string -> string
|
107
|
+
#
|
108
|
+
# Changes underlying String object, the subject of IO.
|
109
|
+
#
|
110
|
+
def string=(str)
|
111
|
+
@string = str.to_str
|
112
|
+
@pos = 0
|
113
|
+
@lineno = 0
|
114
|
+
end
|
115
|
+
|
116
|
+
# strio.rewind -> 0
|
117
|
+
#
|
118
|
+
# Positions *strio* to the beginning of input, resetting
|
119
|
+
# +lineno+ to zero.
|
120
|
+
#
|
121
|
+
def rewind
|
122
|
+
@pos = 0
|
123
|
+
@lineno = 0
|
124
|
+
end
|
125
|
+
|
126
|
+
# strio.read([length [, buffer]]) -> string, buffer, or nil
|
127
|
+
#
|
128
|
+
# See IO#read.
|
129
|
+
#
|
130
|
+
def read(length = nil, buffer = String.new)
|
131
|
+
raise IOError, "not opened for reading" unless @readable
|
132
|
+
raise TypeError unless buffer.respond_to?(:to_str)
|
133
|
+
buffer = buffer.to_str
|
134
|
+
|
135
|
+
if length.nil?
|
136
|
+
return buffer.replace("") if self.eof?
|
137
|
+
buffer.replace(@string[@pos..-1])
|
138
|
+
@pos = @string.size
|
139
|
+
else
|
140
|
+
raise TypeError unless length.respond_to?(:to_int)
|
141
|
+
length = length.to_int
|
142
|
+
raise ArgumentError if length < 0
|
143
|
+
|
144
|
+
if length == 0
|
145
|
+
buffer.replace("")
|
146
|
+
else
|
147
|
+
if self.eof?
|
148
|
+
buffer.replace("")
|
149
|
+
return nil
|
150
|
+
end
|
151
|
+
buffer.replace(@string[@pos, length])
|
152
|
+
@pos += buffer.length
|
153
|
+
end
|
154
|
+
buffer.force_encoding('BINARY')
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
buffer
|
159
|
+
end
|
160
|
+
|
161
|
+
# strio.sysread(integer[, outbuf]) -> string
|
162
|
+
#
|
163
|
+
# Similar to #read, but raises +EOFError+ at end of string instead of
|
164
|
+
# returning +nil+, as well as IO#sysread does.
|
165
|
+
def sysread(length = nil, buffer = String.new)
|
166
|
+
val = read(length, buffer)
|
167
|
+
( buffer.clear && raise(IO::EOFError, "end of file reached")) if val == nil
|
168
|
+
val
|
169
|
+
end
|
170
|
+
alias_method :readpartial, :sysread
|
171
|
+
alias_method :read_nonblock, :sysread
|
172
|
+
|
173
|
+
# strio.readbyte -> fixnum
|
174
|
+
#
|
175
|
+
# See IO#readbyte.
|
176
|
+
#
|
177
|
+
def readbyte
|
178
|
+
raise(IO::EOFError, "end of file reached") if eof?
|
179
|
+
getbyte
|
180
|
+
end
|
181
|
+
|
182
|
+
# strio.seek(amount, whence=SEEK_SET) -> 0
|
183
|
+
#
|
184
|
+
# Seeks to a given offset _amount_ in the stream according to
|
185
|
+
# the value of _whence_ (see IO#seek).
|
186
|
+
#
|
187
|
+
def seek(offset, whence = ::IO::SEEK_SET)
|
188
|
+
raise(IOError, "closed stream") if closed?
|
189
|
+
raise TypeError unless offset.respond_to?(:to_int)
|
190
|
+
offset = offset.to_int
|
191
|
+
|
192
|
+
case whence
|
193
|
+
when ::IO::SEEK_CUR
|
194
|
+
# Seeks to offset plus current position
|
195
|
+
offset += @pos
|
196
|
+
when ::IO::SEEK_END
|
197
|
+
# Seeks to offet plus end of stream (usually offset is a negative value)
|
198
|
+
offset += @string.size
|
199
|
+
when ::IO::SEEK_SET, nil
|
200
|
+
# Seeks to the absolute location given by offset
|
201
|
+
else
|
202
|
+
raise Errno::EINVAL, "invalid whence"
|
203
|
+
end
|
204
|
+
|
205
|
+
raise Errno::EINVAL if (offset < 0)
|
206
|
+
@pos = offset
|
207
|
+
|
208
|
+
0
|
209
|
+
end
|
210
|
+
|
211
|
+
# strio.pos = integer -> integer
|
212
|
+
#
|
213
|
+
# Seeks to the given position (in bytes) in *strio*.
|
214
|
+
#
|
215
|
+
def pos=(pos)
|
216
|
+
raise Errno::EINVAL if pos < 0
|
217
|
+
@pos = pos
|
218
|
+
end
|
219
|
+
|
220
|
+
# strio.closed? -> true or false
|
221
|
+
#
|
222
|
+
# Returns +true+ if *strio* is completely closed, +false+ otherwise.
|
223
|
+
#
|
224
|
+
def closed?
|
225
|
+
!@readable && !@writable
|
226
|
+
end
|
227
|
+
|
228
|
+
# strio.close -> nil
|
229
|
+
#
|
230
|
+
# Closes strio. The *strio* is unavailable for any further data
|
231
|
+
# operations; an +IOError+ is raised if such an attempt is made.
|
232
|
+
#
|
233
|
+
def close
|
234
|
+
raise(IOError, "closed stream") if closed?
|
235
|
+
@readable = @writable = nil
|
236
|
+
end
|
237
|
+
|
238
|
+
# strio.closed_read? -> true or false
|
239
|
+
#
|
240
|
+
# Returns +true+ if *strio* is not readable, +false+ otherwise.
|
241
|
+
#
|
242
|
+
def closed_read?
|
243
|
+
!@readable
|
244
|
+
end
|
245
|
+
|
246
|
+
# strio.close_read -> nil
|
247
|
+
#
|
248
|
+
# Closes the read end of a StringIO. Will raise an +IOError+ if the
|
249
|
+
# *strio* is not readable.
|
250
|
+
#
|
251
|
+
def close_read
|
252
|
+
raise(IOError, "closing non-duplex IO for reading") unless @readable
|
253
|
+
@readable = nil
|
254
|
+
end
|
255
|
+
|
256
|
+
# strio.closed_write? -> true or false
|
257
|
+
#
|
258
|
+
# Returns +true+ if *strio* is not writable, +false+ otherwise.
|
259
|
+
#
|
260
|
+
def closed_write?
|
261
|
+
!@writable
|
262
|
+
end
|
263
|
+
|
264
|
+
# strio.eof -> true or false
|
265
|
+
# strio.eof? -> true or false
|
266
|
+
#
|
267
|
+
# Returns true if *strio* is at end of file. The stringio must be
|
268
|
+
# opened for reading or an +IOError+ will be raised.
|
269
|
+
#
|
270
|
+
def eof?
|
271
|
+
raise(IOError, "not opened for reading") unless @readable
|
272
|
+
@pos >= @string.length
|
273
|
+
end
|
274
|
+
alias_method :eof, :eof?
|
275
|
+
|
276
|
+
def binmode
|
277
|
+
self
|
278
|
+
end
|
279
|
+
|
280
|
+
def fcntl
|
281
|
+
raise NotImplementedError, "StringIO#fcntl is not implemented"
|
282
|
+
end
|
283
|
+
|
284
|
+
def flush
|
285
|
+
self
|
286
|
+
end
|
287
|
+
|
288
|
+
def fsync
|
289
|
+
0
|
290
|
+
end
|
291
|
+
|
292
|
+
# strio.pid -> nil
|
293
|
+
#
|
294
|
+
def pid
|
295
|
+
nil
|
296
|
+
end
|
297
|
+
|
298
|
+
# strio.sync -> true
|
299
|
+
#
|
300
|
+
# Returns +true+ always.
|
301
|
+
#
|
302
|
+
def sync
|
303
|
+
true
|
304
|
+
end
|
305
|
+
|
306
|
+
# strio.sync = boolean -> boolean
|
307
|
+
#
|
308
|
+
def sync=(value)
|
309
|
+
value
|
310
|
+
end
|
311
|
+
|
312
|
+
def tell
|
313
|
+
@pos
|
314
|
+
end
|
315
|
+
|
316
|
+
# strio.fileno -> nil
|
317
|
+
#
|
318
|
+
def fileno
|
319
|
+
nil
|
320
|
+
end
|
321
|
+
|
322
|
+
# strio.isatty -> nil
|
323
|
+
# strio.tty? -> nil
|
324
|
+
def isatty
|
325
|
+
false
|
326
|
+
end
|
327
|
+
alias_method :tty?, :isatty
|
328
|
+
|
329
|
+
def length
|
330
|
+
@string.length
|
331
|
+
end
|
332
|
+
alias_method :size, :length
|
333
|
+
|
334
|
+
# strio.getc -> string or nil
|
335
|
+
#
|
336
|
+
# Gets the next character from io.
|
337
|
+
# Returns nil if called at end of file
|
338
|
+
def getc
|
339
|
+
raise(IOError, "not opened for reading") unless @readable
|
340
|
+
return nil if eof?
|
341
|
+
result = @string[@pos]
|
342
|
+
@pos += 1
|
343
|
+
result
|
344
|
+
end
|
345
|
+
|
346
|
+
# strio.ungetc(string) -> nil
|
347
|
+
#
|
348
|
+
# Pushes back one character (passed as a parameter) onto *strio*
|
349
|
+
# such that a subsequent buffered read will return it. Pushing back
|
350
|
+
# behind the beginning of the buffer string is not possible. Nothing
|
351
|
+
# will be done if such an attempt is made.
|
352
|
+
# In other case, there is no limitation for multiple pushbacks.
|
353
|
+
#
|
354
|
+
def ungetc(chars)
|
355
|
+
raise(IOError, "not opened for reading") unless @readable
|
356
|
+
return nil if chars == nil
|
357
|
+
|
358
|
+
chars = chars.chr if chars.kind_of?(Fixnum)
|
359
|
+
raise TypeError unless chars.respond_to?(:to_str)
|
360
|
+
chars = chars.to_str
|
361
|
+
|
362
|
+
if @pos == 0
|
363
|
+
@string = chars + @string
|
364
|
+
elsif @pos > 0
|
365
|
+
@pos -= 1
|
366
|
+
@string[@pos] = chars
|
367
|
+
end
|
368
|
+
|
369
|
+
nil
|
370
|
+
end
|
371
|
+
|
372
|
+
# strio.ungetbyte(fixnum) -> nil
|
373
|
+
#
|
374
|
+
# See IO#ungetbyte
|
375
|
+
#
|
376
|
+
def ungetbyte(bytes)
|
377
|
+
raise(IOError, "not opened for reading") unless @readable
|
378
|
+
return nil if bytes == nil
|
379
|
+
|
380
|
+
bytes = bytes.chr if bytes.kind_of?(Fixnum)
|
381
|
+
raise TypeError unless bytes.respond_to?(:to_str)
|
382
|
+
bytes = bytes.to_str
|
383
|
+
|
384
|
+
if @pos == 0
|
385
|
+
@string = bytes + @string
|
386
|
+
elsif @pos > 0
|
387
|
+
@pos -= 1
|
388
|
+
@string[@pos] = bytes
|
389
|
+
end
|
390
|
+
|
391
|
+
nil
|
392
|
+
end
|
393
|
+
|
394
|
+
# strio.readchar -> fixnum
|
395
|
+
#
|
396
|
+
# See IO#readchar.
|
397
|
+
#
|
398
|
+
def readchar
|
399
|
+
raise(IO::EOFError, "end of file reached") if eof?
|
400
|
+
getc
|
401
|
+
end
|
402
|
+
|
403
|
+
# strio.each_char {|char| block } -> strio
|
404
|
+
#
|
405
|
+
# See IO#each_char.
|
406
|
+
#
|
407
|
+
def each_char
|
408
|
+
raise(IOError, "not opened for reading") unless @readable
|
409
|
+
if block_given?
|
410
|
+
@string.each_char{|c| yield(c)}
|
411
|
+
self
|
412
|
+
else
|
413
|
+
@string.each_char
|
414
|
+
end
|
415
|
+
end
|
416
|
+
alias_method :chars, :each_char
|
417
|
+
|
418
|
+
# strio.getbyte -> fixnum or nil
|
419
|
+
#
|
420
|
+
# See IO#getbyte.
|
421
|
+
def getbyte
|
422
|
+
raise(IOError, "not opened for reading") unless @readable
|
423
|
+
# Because we currently don't support bytes access
|
424
|
+
# the following code isn't used
|
425
|
+
# instead we are dealing with chars
|
426
|
+
result = @string.bytes.to_a[@pos]
|
427
|
+
@pos += 1 unless eof?
|
428
|
+
result
|
429
|
+
# getc
|
430
|
+
end
|
431
|
+
|
432
|
+
# strio.each_byte {|byte| block } -> strio
|
433
|
+
#
|
434
|
+
# See IO#each_byte.
|
435
|
+
#
|
436
|
+
def each_byte
|
437
|
+
raise(IOError, "not opened for reading") unless @readable
|
438
|
+
return self if (@pos > @string.length)
|
439
|
+
if block_given?
|
440
|
+
@string.each_byte{|b| @pos += 1; yield(b)}
|
441
|
+
self
|
442
|
+
else
|
443
|
+
@string.each_byte
|
444
|
+
end
|
445
|
+
end
|
446
|
+
alias_method :bytes, :each_byte
|
447
|
+
|
448
|
+
|
449
|
+
# strio.each(sep=$/) {|line| block } -> strio
|
450
|
+
# strio.each(limit) {|line| block } -> strio
|
451
|
+
# strio.each(sep, limit) {|line| block } -> strio
|
452
|
+
# strio.each_line(sep=$/) {|line| block } -> strio
|
453
|
+
# strio.each_line(limit) {|line| block } -> strio
|
454
|
+
# strio.each_line(sep,limit) {|line| block } -> strio
|
455
|
+
#
|
456
|
+
# See IO#each.
|
457
|
+
#
|
458
|
+
def each(sep=$/, limit=nil)
|
459
|
+
if block_given?
|
460
|
+
raise(IOError, "not opened for reading") unless @readable
|
461
|
+
sep, limit = getline_args(sep, limit)
|
462
|
+
if limit == 0
|
463
|
+
raise ArgumentError, "invalid limit: 0 for each and family"
|
464
|
+
end
|
465
|
+
while line = getline(sep, limit)
|
466
|
+
yield(line)
|
467
|
+
end
|
468
|
+
self
|
469
|
+
else
|
470
|
+
to_enum(:each, sep, limit)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
alias_method :each_line, :each
|
474
|
+
alias_method :lines, :each
|
475
|
+
|
476
|
+
# strio.gets(sep=$/) -> string or nil
|
477
|
+
# strio.gets(limit) -> string or nil
|
478
|
+
# strio.gets(sep, limit) -> string or nil
|
479
|
+
#
|
480
|
+
# See IO#gets.
|
481
|
+
#
|
482
|
+
def gets(sep=$/, limit=nil)
|
483
|
+
sep, limit = getline_args(sep, limit)
|
484
|
+
$_ = getline(sep, limit)
|
485
|
+
end
|
486
|
+
|
487
|
+
# strio.readline(sep=$/) -> string
|
488
|
+
# strio.readline(limit) -> string or nil
|
489
|
+
# strio.readline(sep, limit) -> string or nil
|
490
|
+
#
|
491
|
+
# See IO#readline.
|
492
|
+
def readline(sep=$/, limit=nil)
|
493
|
+
raise(IO::EOFError, 'end of file reached') if eof?
|
494
|
+
sep, limit = getline_args(sep, limit)
|
495
|
+
$_ = getline(sep, limit)
|
496
|
+
end
|
497
|
+
|
498
|
+
# strio.readlines(sep=$/) -> array
|
499
|
+
# strio.readlines(limit) -> array
|
500
|
+
# strio.readlines(sep,limit) -> array
|
501
|
+
#
|
502
|
+
# See IO#readlines.
|
503
|
+
#
|
504
|
+
def readlines(sep=$/, limit=nil)
|
505
|
+
raise IOError, "not opened for reading" unless @readable
|
506
|
+
ary = []
|
507
|
+
sep, limit = getline_args(sep, limit)
|
508
|
+
if limit == 0
|
509
|
+
raise ArgumentError, "invalid limit: 0 for readlines"
|
510
|
+
end
|
511
|
+
while line = getline(sep, limit)
|
512
|
+
ary << line
|
513
|
+
end
|
514
|
+
ary
|
515
|
+
end
|
516
|
+
|
517
|
+
|
518
|
+
# strio.write(string) -> integer
|
519
|
+
# strio.syswrite(string) -> integer
|
520
|
+
#
|
521
|
+
# Appends the given string to the underlying buffer string of *strio*.
|
522
|
+
# The stream must be opened for writing. If the argument is not a
|
523
|
+
# string, it will be converted to a string using <code>to_s</code>.
|
524
|
+
# Returns the number of bytes written. See IO#write.
|
525
|
+
#
|
526
|
+
def write(str)
|
527
|
+
raise(IOError, "not opened for writing") unless @writable
|
528
|
+
raise(IOError, "not modifiable string") if @string.frozen?
|
529
|
+
|
530
|
+
str = str.to_s
|
531
|
+
return 0 if str.empty?
|
532
|
+
|
533
|
+
if @append || (@pos >= @string.length)
|
534
|
+
# add padding in case it's needed
|
535
|
+
str = str.rjust((@pos + str.length) - @string.length, "\000") if (@pos > @string.length)
|
536
|
+
enc1, enc2 = str.encoding, @string.encoding
|
537
|
+
if enc1 != enc2
|
538
|
+
str = str.dup.force_encoding(enc2)
|
539
|
+
end
|
540
|
+
@string << str
|
541
|
+
@pos = @string.length
|
542
|
+
else
|
543
|
+
@string[@pos, str.length] = str
|
544
|
+
@pos += str.length
|
545
|
+
@string.taint if str.tainted?
|
546
|
+
end
|
547
|
+
|
548
|
+
str.length
|
549
|
+
end
|
550
|
+
alias_method :syswrite, :write
|
551
|
+
alias_method :write_nonblock, :write
|
552
|
+
|
553
|
+
# strio << obj -> strio
|
554
|
+
#
|
555
|
+
# See IO#<<.
|
556
|
+
#
|
557
|
+
def <<(str)
|
558
|
+
self.write(str)
|
559
|
+
self
|
560
|
+
end
|
561
|
+
|
562
|
+
|
563
|
+
def close_write
|
564
|
+
raise(IOError, "closing non-duplex IO for writing") unless @writable
|
565
|
+
@writable = nil
|
566
|
+
end
|
567
|
+
|
568
|
+
# strio.truncate(integer) -> 0
|
569
|
+
#
|
570
|
+
# Truncates the buffer string to at most _integer_ bytes. The *strio*
|
571
|
+
# must be opened for writing.
|
572
|
+
#
|
573
|
+
def truncate(len)
|
574
|
+
raise(IOError, "closing non-duplex IO for writing") unless @writable
|
575
|
+
raise(TypeError) unless len.respond_to?(:to_int)
|
576
|
+
length = len.to_int
|
577
|
+
raise(Errno::EINVAL, "negative length") if (length < 0)
|
578
|
+
if length < @string.size
|
579
|
+
@string[length .. @string.size] = ""
|
580
|
+
else
|
581
|
+
@string = @string.ljust(length, "\000")
|
582
|
+
end
|
583
|
+
# send back what was passed, not our :to_int version
|
584
|
+
len
|
585
|
+
end
|
586
|
+
|
587
|
+
# strio.puts(obj, ...) -> nil
|
588
|
+
#
|
589
|
+
# Writes the given objects to <em>strio</em> as with
|
590
|
+
# <code>IO#print</code>. Writes a record separator (typically a
|
591
|
+
# newline) after any that do not already end with a newline sequence.
|
592
|
+
# If called with an array argument, writes each element on a new line.
|
593
|
+
# If called without arguments, outputs a single record separator.
|
594
|
+
#
|
595
|
+
# io.puts("this", "is", "a", "test")
|
596
|
+
#
|
597
|
+
# <em>produces:</em>
|
598
|
+
#
|
599
|
+
# this
|
600
|
+
# is
|
601
|
+
# a
|
602
|
+
# test
|
603
|
+
#
|
604
|
+
def puts(*args)
|
605
|
+
if args.empty?
|
606
|
+
write("\n")
|
607
|
+
else
|
608
|
+
args.each do |arg|
|
609
|
+
if arg == nil
|
610
|
+
line = "nil"
|
611
|
+
else
|
612
|
+
begin
|
613
|
+
arg = arg.to_ary
|
614
|
+
recur = false
|
615
|
+
arg.each do |a|
|
616
|
+
if arg == a
|
617
|
+
recur = true
|
618
|
+
break
|
619
|
+
else
|
620
|
+
puts a
|
621
|
+
end
|
622
|
+
end
|
623
|
+
next unless recur
|
624
|
+
line = '[...]'
|
625
|
+
rescue
|
626
|
+
line = arg.to_s
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
write(line)
|
631
|
+
write("\n") if line[-1] != ?\n
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
nil
|
636
|
+
end
|
637
|
+
|
638
|
+
|
639
|
+
# strio.putc(obj) -> obj
|
640
|
+
#
|
641
|
+
# If <i>obj</i> is <code>Numeric</code>, write the character whose
|
642
|
+
# code is <i>obj</i>, otherwise write the first character of the
|
643
|
+
# string representation of <i>obj</i> to <em>strio</em>.
|
644
|
+
#
|
645
|
+
def putc(obj)
|
646
|
+
raise(IOError, "not opened for writing") unless @writable
|
647
|
+
|
648
|
+
if obj.is_a?(String)
|
649
|
+
char = obj[0]
|
650
|
+
else
|
651
|
+
raise TypeError unless obj.respond_to?(:to_int)
|
652
|
+
char = obj.to_int % 256
|
653
|
+
end
|
654
|
+
|
655
|
+
if @append || @pos == @string.length
|
656
|
+
@string << char
|
657
|
+
@pos = @string.length
|
658
|
+
elsif @pos > @string.length
|
659
|
+
@string = @string.ljust(@pos, "\000")
|
660
|
+
@string << char
|
661
|
+
@pos = @string.length
|
662
|
+
else
|
663
|
+
@string[@pos] = ("" << char)
|
664
|
+
@pos += 1
|
665
|
+
end
|
666
|
+
|
667
|
+
obj
|
668
|
+
end
|
669
|
+
|
670
|
+
|
671
|
+
# strio.print() => nil
|
672
|
+
# strio.print(obj, ...) => nil
|
673
|
+
#
|
674
|
+
# Writes the given object(s) to <em>strio</em>. The stream must be
|
675
|
+
# opened for writing. If the output record separator (<code>$\\</code>)
|
676
|
+
# is not <code>nil</code>, it will be appended to the output. If no
|
677
|
+
# arguments are given, prints <code>$_</code>. Objects that aren't
|
678
|
+
# strings will be converted by calling their <code>to_s</code> method.
|
679
|
+
# With no argument, prints the contents of the variable <code>$_</code>.
|
680
|
+
# Returns <code>nil</code>.
|
681
|
+
#
|
682
|
+
# io.print("This is ", 100, " percent.\n")
|
683
|
+
#
|
684
|
+
# <em>produces:</em>
|
685
|
+
#
|
686
|
+
# This is 100 percent.
|
687
|
+
#
|
688
|
+
def print(*args)
|
689
|
+
raise IOError, "not opened for writing" unless @writable
|
690
|
+
args << $_ if args.empty?
|
691
|
+
args.map! { |x| (x == nil) ? "nil" : x }
|
692
|
+
write((args << $\).flatten.join)
|
693
|
+
nil
|
694
|
+
end
|
695
|
+
|
696
|
+
# printf(strio, string [, obj ... ] ) => nil
|
697
|
+
#
|
698
|
+
# Equivalent to:
|
699
|
+
# strio.write(sprintf(string, obj, ...)
|
700
|
+
#
|
701
|
+
def printf(*args)
|
702
|
+
raise IOError, "not opened for writing" unless @writable
|
703
|
+
|
704
|
+
if args.size > 1
|
705
|
+
write(args.shift % args)
|
706
|
+
else
|
707
|
+
write(args.first)
|
708
|
+
end
|
709
|
+
|
710
|
+
nil
|
711
|
+
end
|
712
|
+
|
713
|
+
def external_encoding
|
714
|
+
@string ? @string.encoding : nil
|
715
|
+
end
|
716
|
+
|
717
|
+
def internal_encoding
|
718
|
+
nil
|
719
|
+
end
|
720
|
+
|
721
|
+
def set_encoding(enc)
|
722
|
+
@string = @string.encode(enc)
|
723
|
+
self
|
724
|
+
end
|
725
|
+
|
726
|
+
protected
|
727
|
+
|
728
|
+
# meant to be overwritten by developers
|
729
|
+
def to_strio
|
730
|
+
self
|
731
|
+
end
|
732
|
+
|
733
|
+
def define_mode(mode=nil)
|
734
|
+
if mode == nil
|
735
|
+
# default modes
|
736
|
+
@string.frozen? ? set_mode_from_string("r") : set_mode_from_string("r+")
|
737
|
+
elsif mode.is_a?(Integer)
|
738
|
+
set_mode_from_integer(mode)
|
739
|
+
else
|
740
|
+
mode = mode.to_str
|
741
|
+
set_mode_from_string(mode)
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
def set_mode_from_string(mode)
|
746
|
+
@readable = @writable = @append = false
|
747
|
+
|
748
|
+
case mode
|
749
|
+
when "r", "rb"
|
750
|
+
@readable = true
|
751
|
+
when "r+", "rb+"
|
752
|
+
raise(Errno::EACCES) if @string.frozen?
|
753
|
+
@readable = true
|
754
|
+
@writable = true
|
755
|
+
when "w", "wb"
|
756
|
+
@string.frozen? ? raise(Errno::EACCES) : @string.replace("")
|
757
|
+
@writable = true
|
758
|
+
when "w+", "wb+"
|
759
|
+
@string.frozen? ? raise(Errno::EACCES) : @string.replace("")
|
760
|
+
@readable = true
|
761
|
+
@writable = true
|
762
|
+
when "a", "ab"
|
763
|
+
raise(Errno::EACCES) if @string.frozen?
|
764
|
+
@writable = true
|
765
|
+
@append = true
|
766
|
+
when "a+", "ab+"
|
767
|
+
raise(Errno::EACCES) if @string.frozen?
|
768
|
+
@readable = true
|
769
|
+
@writable = true
|
770
|
+
@append = true
|
771
|
+
end
|
772
|
+
end
|
773
|
+
|
774
|
+
def set_mode_from_integer(mode)
|
775
|
+
@readable = @writable = @append = false
|
776
|
+
|
777
|
+
case mode & (IO::RDONLY | IO::WRONLY | IO::RDWR)
|
778
|
+
when IO::RDONLY
|
779
|
+
@readable = true
|
780
|
+
@writable = false
|
781
|
+
when IO::WRONLY
|
782
|
+
@readable = false
|
783
|
+
@writable = true
|
784
|
+
raise(Errno::EACCES) if @string.frozen?
|
785
|
+
when IO::RDWR
|
786
|
+
@readable = true
|
787
|
+
@writable = true
|
788
|
+
raise(Errno::EACCES) if @string.frozen?
|
789
|
+
end
|
790
|
+
|
791
|
+
@append = true if (mode & IO::APPEND) != 0
|
792
|
+
raise(Errno::EACCES) if @append && @string.frozen?
|
793
|
+
@string.replace("") if (mode & IO::TRUNC) != 0
|
794
|
+
end
|
795
|
+
|
796
|
+
def getline(sep = $/, lim = nil)
|
797
|
+
raise(IOError, "not opened for reading") unless @readable
|
798
|
+
return nil if eof?
|
799
|
+
|
800
|
+
offset = limit = -1
|
801
|
+
if lim != nil
|
802
|
+
limit = lim - 1
|
803
|
+
offset = @pos + limit
|
804
|
+
end
|
805
|
+
|
806
|
+
if lim != nil && lim == 0
|
807
|
+
line = ""
|
808
|
+
elsif sep == nil
|
809
|
+
line = @string[@pos .. offset]
|
810
|
+
elsif sep.empty?
|
811
|
+
while @string[@pos] == ?\n
|
812
|
+
@pos += 1
|
813
|
+
limit -= 1
|
814
|
+
end
|
815
|
+
|
816
|
+
if stop = @string.index("\n\n", @pos)
|
817
|
+
stop += 1
|
818
|
+
line = @string[@pos .. stop]
|
819
|
+
if lim != nil && line[limit, 2] != "\n\n"
|
820
|
+
line = line[0 .. limit]
|
821
|
+
end
|
822
|
+
else
|
823
|
+
line = @string[@pos .. offset]
|
824
|
+
end
|
825
|
+
else
|
826
|
+
if stop = @string.index(sep, @pos)
|
827
|
+
line = @string[@pos .. (stop + sep.size - 1)]
|
828
|
+
else
|
829
|
+
line = @string[@pos .. offset]
|
830
|
+
end
|
831
|
+
end
|
832
|
+
@pos += line.size
|
833
|
+
@lineno += 1
|
834
|
+
|
835
|
+
line
|
836
|
+
end
|
837
|
+
|
838
|
+
def getline_args(sep = $/, lim = nil)
|
839
|
+
if lim == nil && !sep.kind_of?(String)
|
840
|
+
if !sep.respond_to?(:to_str)
|
841
|
+
lim = sep
|
842
|
+
sep = nil
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
if lim != nil
|
847
|
+
raise TypeError unless lim.respond_to?(:to_int)
|
848
|
+
lim = lim.to_int
|
849
|
+
end
|
850
|
+
sep = sep.to_str unless (sep == nil)
|
851
|
+
|
852
|
+
return sep, lim
|
853
|
+
end
|
854
|
+
|
855
|
+
end
|
data/lib/motion-csv/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-csv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Rickert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
|
15
|
-
prerelease: false
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
14
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
15
|
requirements:
|
18
16
|
- - ! '>='
|
19
17
|
- !ruby/object:Gem::Version
|
20
18
|
version: '0'
|
21
|
-
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
name: rake
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
22
23
|
requirements:
|
23
24
|
- - ! '>='
|
24
25
|
- !ruby/object:Gem::Version
|
25
26
|
version: '0'
|
26
|
-
type: :development
|
27
27
|
description: ! 'This is a RubyMotion friendly port of fasterer-csv by Mason: http://rubygems.org/gems/fasterer-csv'
|
28
28
|
email:
|
29
29
|
- mjar81@gmail.com
|
@@ -33,6 +33,7 @@ extra_rdoc_files: []
|
|
33
33
|
files:
|
34
34
|
- README.md
|
35
35
|
- lib/motion-csv/motion-csv.rb
|
36
|
+
- lib/motion-csv/stringio.rb
|
36
37
|
- lib/motion-csv/version.rb
|
37
38
|
- lib/motion-csv.rb
|
38
39
|
homepage:
|
@@ -55,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
56
|
version: '0'
|
56
57
|
requirements: []
|
57
58
|
rubyforge_project:
|
58
|
-
rubygems_version: 2.
|
59
|
+
rubygems_version: 2.1.9
|
59
60
|
signing_key:
|
60
61
|
specification_version: 4
|
61
62
|
summary: ! 'This is a RubyMotion friendly port of fasterer-csv by Mason: http://rubygems.org/gems/fasterer-csv'
|