Class: SakaiInfo::ContentBinaryEntity

Inherits:
Object
  • Object
show all
Defined in:
lib/sakai-info/content.rb

Constant Summary collapse

MAX_HUGE_INT =
(2**64 - 1)
CR_BLOCK1 =

content resource block IDs yes, block 2 = 12 and block 3 = 11 BLOCK1 = general attributes

10
CR_BLOCK2 =

BLOCK2 = release and retract dates

12
CR_BLOCK3 =

BLOCK3 = groups

11
CR_BLOCK4 =

BLOCK4 = properties

13
CR_BLOCK5 =

BLOCK5 = file properties

14
CR_BLOCK6 =

BLOCK6 = byte[] storing file content if it’s not in the filesystem

15
CR_BLOCK_END =

BLOCK_END

2
CC_BLOCK1 =

content collection block IDs BLOCK1 = general attributes

10
CC_BLOCK2 =

BLOCK2 = release and retract dates

11
CC_BLOCK3 =

BLOCK3 = groups

12
CC_BLOCK4 =

BLOCK4 = properties

13
CC_BLOCK_END =

BLOCK_END

2
PROPS_BLOCK1 =

properties block types

100
PROPS_BLOCK2 =
101
PROPS_BLOCK3 =
102

Instance Method Summary collapse

Constructor Details

#initialize(raw_blob) ⇒ ContentBinaryEntity

Returns a new instance of ContentBinaryEntity.



532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'lib/sakai-info/content.rb', line 532

def initialize(raw_blob)
  blob = StringIO.new(raw_blob)
  blob_id = blob.read(6)

  serialization_type = read_long_int(blob)
  if serialization_type != 1
    raise UnknownBinaryEntityFormat.new("Unrecognized format version #{serialization_type}")
  end

  @properties = {}

  if blob_id == "CHSBRE"
    parse_for_content_resource(blob)
  elsif blob_id == "CHSBCE"
    parse_for_content_collection(blob)
  else
    raise UnknownBinaryEntityFormat.new("Unrecognized format ID: #{blob_id}")
  end
end

Instance Method Details

#[](key) ⇒ Object



552
553
554
# File 'lib/sakai-info/content.rb', line 552

def [](key)
  @properties[key]
end

#keysObject



556
557
558
# File 'lib/sakai-info/content.rb', line 556

def keys
  @properties.keys
end

#parse_block1(blob) ⇒ Object



654
655
656
657
658
659
# File 'lib/sakai-info/content.rb', line 654

def parse_block1(blob)
  @properties["id"] = read_utf_string(blob)
  @properties["resource_type"] = read_utf_string(blob)
  @properties["access_mode"] = read_utf_string(blob)
  @properties["is_hidden"] = (read_tiny_int(blob) != 0)
end

#parse_block2(blob) ⇒ Object



661
662
663
664
665
666
667
668
669
670
671
# File 'lib/sakai-info/content.rb', line 661

def parse_block2(blob)
  @properties["release_date"] = read_huge_int(blob)
  if @properties["release_date"] == MAX_HUGE_INT
    @properties["release_date"] = nil
  end

  @properties["retract_date"] = read_huge_int(blob)
  if @properties["retract_date"] == MAX_HUGE_INT
    @properties["retract_date"] = nil
  end
end

#parse_block3(blob) ⇒ Object



673
674
675
676
677
678
679
680
681
# File 'lib/sakai-info/content.rb', line 673

def parse_block3(blob)
  group_count = read_long_int(blob)
  @properties["groups"] = []
  if group_count > 0
    group_count.times do
      @properties["groups"] << read_utf_string(blob)
    end
  end
end

#parse_block4(blob) ⇒ Object



688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
# File 'lib/sakai-info/content.rb', line 688

def parse_block4(blob)
  type = read_long_int(blob)
  if type != 1
    raise UnknownBinaryEntityFormat.new("Unknown properties serialization type #{type}")
  end

  props_block_number = read_long_int(blob)
  if props_block_number == PROPS_BLOCK1
    props_count = read_long_int(blob)
  else
    raise UnknownBinaryEntityFormat.new("Unable to parse properties block")
  end

  props_count.times do
    props_block_number = read_long_int(blob)
    case props_block_number
    when PROPS_BLOCK2
      key = read_utf_string(blob)
      value = read_utf_string(blob)
      @properties[key] = value
    when PROPS_BLOCK3
      key = read_utf_string(blob)
      @properties[key] = []
      value_count = read_long_int(blob)
      value_count.times do
        @properties[key] << read_utf_string(blob)
      end
    else
      raise UnknownBinaryEntityFormat.new("Unknown Property Block ID: '#{block_number}'")
    end
  end
end

#parse_for_content_collection(blob) ⇒ Object



629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'lib/sakai-info/content.rb', line 629

def parse_for_content_collection(blob)
  while true
    block_number = read_long_int(blob)
    case(block_number)
    when CC_BLOCK1
      parse_block1(blob)

    when CC_BLOCK2
      parse_block2(blob)

    when CC_BLOCK3
      parse_block3(blob)

    when CC_BLOCK4
      parse_block4(blob)

    when CC_BLOCK_END
      break

    else
      raise UnknownBinaryEntityFormat.new("Unknown Block ID: '#{block_number}'")
    end
  end
end

#parse_for_content_resource(blob) ⇒ Object



581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
# File 'lib/sakai-info/content.rb', line 581

def parse_for_content_resource(blob)
  while true
    block_number = read_long_int(blob)
    case(block_number)
    when CR_BLOCK1
      parse_block1(blob)

    when CR_BLOCK2
      parse_block2(blob)

    when CR_BLOCK3
      parse_block3(blob)

    when CR_BLOCK4
      parse_block4(blob)

    when CR_BLOCK5
      @properties["content_type"] = read_utf_string(blob)
      @properties["content_length"] = read_huge_int(blob)
      @properties["file_path"] = read_utf_string(blob)

    when CR_BLOCK6
      body_size = read_long_int(blob)
      if body_size > 0
        STDERR.puts "WARNING: files stored in the database are not currently supported"
      end

    when CR_BLOCK_END
      break

    else
      raise UnknownBinaryEntityFormat.new("Unknown Block ID: '#{block_number}'")
    end
  end
end

#read_huge_int(bin) ⇒ Object



516
517
518
519
520
521
# File 'lib/sakai-info/content.rb', line 516

def read_huge_int(bin)
  part1 = bin.read(4).unpack("N")[0]
  part2 = bin.read(4).unpack("N")[0]

  return ((part1 << 32) + part2)
end

#read_int(bin) ⇒ Object



508
509
510
# File 'lib/sakai-info/content.rb', line 508

def read_int(bin)
  bin.read(2).unpack("n")[0]
end

#read_long_int(bin) ⇒ Object



512
513
514
# File 'lib/sakai-info/content.rb', line 512

def read_long_int(bin)
  bin.read(4).unpack("N")[0]
end

#read_tiny_int(bin) ⇒ Object



504
505
506
# File 'lib/sakai-info/content.rb', line 504

def read_tiny_int(bin)
  bin.read(1).unpack("C")[0]
end

#read_utf_string(bin) ⇒ Object



524
525
526
527
528
529
530
# File 'lib/sakai-info/content.rb', line 524

def read_utf_string(bin)
  byte_length = read_int(bin)
  if byte_length == 0
    return ""
  end
  bin.read(byte_length).force_encoding(Encoding::UTF_8)
end

#to_hashObject



560
561
562
# File 'lib/sakai-info/content.rb', line 560

def to_hash
  @properties
end