Class: Excel::SharedStringTable

Inherits:
Object
  • Object
show all
Extended by:
UnicodeUtils
Includes:
UnicodeUtils
Defined in:
lib/ru_excel/biff_records.rb

Constant Summary collapse

SST_ID =
0x00FC
CONTINUE_ID =
0x003C

Instance Method Summary collapse

Methods included from UnicodeUtils

u2bytes, u2ints, upack1, upack2

Constructor Details

#initializeSharedStringTable

Returns a new instance of SharedStringTable.



12
13
14
15
16
17
18
19
20
# File 'lib/ru_excel/biff_records.rb', line 12

def initialize
    @sst_record = ''
    @continues = []
    @current_piece = [ 0, 0].pack('VV')
    @pos = @current_piece.length

    @str_indexes = {}
    @add_calls = 0
end

Instance Method Details

#add_str(s) ⇒ Object



22
23
24
25
26
27
28
29
# File 'lib/ru_excel/biff_records.rb', line 22

def add_str(s)
    @add_calls += 1
    unless (ret = @str_indexes[s])
        ret = @str_indexes[s] = @str_indexes.length
        add_to_sst(s)
    end
    ret
end

#add_to_sst(s) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/ru_excel/biff_records.rb', line 43

def add_to_sst(s)
    u_str = upack2(s)
    raise Exception('error=> very long string.') if u_str.length > 0xFFFF
    
    is_unicode_str = u_str[2] == ?\1
    if is_unicode_str
        atom_len = 5 # 2 byte -- len,
                     # 1 byte -- options,
                     # 2 byte -- 1st sym
    else
        atom_len = 4 # 2 byte -- len,
                     # 1 byte -- options,
                     # 1 byte -- 1st sym
    end

    save_atom(u_str[(0)...(atom_len)])
    save_splitted(u_str[(atom_len)..-1], is_unicode_str)
end

#get_biff_recordObject



35
36
37
38
39
40
41
# File 'lib/ru_excel/biff_records.rb', line 35

def get_biff_record
    new_piece
    result = [SST_ID, @sst_record.length, @add_calls, @str_indexes.length].pack('vvVV')
    result << @sst_record[(8)..-1]
    result << @continues.join('')
    result
end

#new_pieceObject



62
63
64
65
66
67
68
69
70
71
# File 'lib/ru_excel/biff_records.rb', line 62

def new_piece
    if @sst_record == ''
        @sst_record = @current_piece
    else
        curr_piece_len = @current_piece.length
        @continues << [ CONTINUE_ID, @current_piece.length, @current_piece].pack('vva*')
    end
    @current_piece = ''
    @pos = @current_piece.length
end

#save_atom(s) ⇒ Object



73
74
75
76
77
78
# File 'lib/ru_excel/biff_records.rb', line 73

def save_atom(s)
    atom_len = s.length
    free_space = 0x2020 - @current_piece.length
    new_piece() if free_space < atom_len
    @current_piece += s
end

#save_splitted(s, is_unicode_str) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ru_excel/biff_records.rb', line 80

def save_splitted(s, is_unicode_str)
    i = 0
    str_len = s.length
    while i < str_len
        piece_len = @current_piece.length
        free_space = 0x2020 - piece_len
        tail_len = str_len - i
        need_more_space = free_space < tail_len

        atom_len = need_more_space ? (is_unicode_str ? free_space & 0xFFFE : free_space) : tail_len

        @current_piece += s[(i)...(i+atom_len)]

        if need_more_space
            new_piece()
            @current_piece += is_unicode_str ? "\x01" : "\x00"
        end
        i += atom_len
    end
end

#str_index(s) ⇒ Object



31
32
33
# File 'lib/ru_excel/biff_records.rb', line 31

def str_index(s)
    @str_indexes[s]
end