Method: BlueFeather::Document.parse_io

Defined in:
lib/bluefeather.rb

.parse_io(input, default_enc = EncodingType::UTF8) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/bluefeather.rb', line 200

def parse_io(input, default_enc = EncodingType::UTF8)
  headers = {}
  body = nil
  first_pos = input.pos
  
  Util.change_kcode(EncodingType.type_to_kcode(default_enc)){
    # default encoding

    if defined?(Encoding) then
      input.set_encoding(Encoding.find(default_enc))
    end
    
    
    
    # get headers

    pos_before_gets = nil
    first_line = true

    loop do
      pos_before_gets = input.pos
      line = input.gets
      
      # cut UTF-8 BOM

      if first_line and line =~ UTF8_BOM_PATTERN then
        line.slice!(UTF8_BOM_PATTERN)
      end  
      first_line = false
      
      if line and line.chomp =~ HEADER_PATTERN then
        key = $1.downcase; value = $2
        
        if key == 'encoding' and not headers.include?('encoding') then
          kc = EncodingType.type_to_kcode(value.downcase)
          if input.respond_to?(:set_encoding) then
            input.set_encoding(value.downcase)
            
            # rewind (reason => [ruby-list:45988])

            input.pos = first_pos
            first_line = true
          else
            $KCODE = kc
          end
        end
        
        headers[key] = value
      else
        # EOF or Metadata end

        break
      end
    end
    
    # back

    input.pos = pos_before_gets
    
    
    
    # skip blank lines

    loop do
      pos_before_gets = input.pos

      line = input.gets
      if line.nil? or not line =~ BLANK_LINE_PATTERN then
        break
      end
    end
    
    # back

    input.pos = pos_before_gets
    
    
    
    # get body

    body = input.read

  }
  
  
  return self.new(headers, body)
end