// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2012 * Lei Wen , Marvell Inc. */ #include #include #include #include #include #include #include #include "zlib/zutil.h" #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ #define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200 #endif #define ZALLOC_ALIGNMENT 16 static void *zalloc(void *x, unsigned items, unsigned size) { void *p; size *= items; size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); p = malloc_cache_aligned(size); return (p); } static void zfree(void *x, void *addr, unsigned nb) { free (addr); } int gzip(void *dst, unsigned long *lenp, unsigned char *src, unsigned long srclen) { return zzip(dst, lenp, src, srclen, 1, NULL); } /* * Compress blocks with zlib */ int zzip(void *dst, unsigned long *lenp, unsigned char *src, unsigned long srclen, int stoponerr, int (*func)(unsigned long, unsigned long)) { z_stream s; int r, flush, orig, window; unsigned long comp_len, left_len; if (!srclen) return 0; #ifndef CONFIG_GZIP window = MAX_WBITS; #else window = 2 * MAX_WBITS; #endif orig = *lenp; s.zalloc = zalloc; s.zfree = zfree; s.opaque = Z_NULL; r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, sizeof(z_stream)); if (r != Z_OK) { printf ("Error: deflateInit2_() returned %d\n", r); return -1; } while (srclen > 0) { comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ? CONFIG_GZIP_COMPRESS_DEF_SZ : srclen; s.next_in = src; s.avail_in = comp_len; flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)? Z_NO_FLUSH : Z_FINISH; do { left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ? CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp; s.next_out = dst; s.avail_out = left_len; r = deflate(&s, flush); if (r == Z_STREAM_ERROR && stoponerr == 1) { printf("Error: deflate() returned %d\n", r); r = -1; goto bail; } if (!func) { dst += (left_len - s.avail_out); *lenp -= (left_len - s.avail_out); } else if (left_len - s.avail_out > 0) { r = func((unsigned long)dst, left_len - s.avail_out); if (r < 0) goto bail; } } while (s.avail_out == 0 && (*lenp > 0)); if (s.avail_in) { printf("Deflate failed to consume %u bytes", s.avail_in); r = -1; goto bail; } if (*lenp == 0) { printf("Deflate need more space to compress " "left %lu bytes\n", srclen); r = -1; goto bail; } srclen -= comp_len; src += comp_len; } r = 0; bail: deflateEnd(&s); *lenp = orig - *lenp; return r; } '>
blob: 878619f58a575cd39c776917bef9bcbae2f9ad61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env ruby -w
# encoding: UTF-8

# tc_serialization.rb
#
#  Created by James Edward Gray II on 2005-10-31.
#  Copyright 2005 James Edward Gray II. You can redistribute or modify this code
#  under the terms of Ruby's license.

require "test/unit"

require "csv"

# An example of how to provide custom CSV serialization.
class Hash
  def self.csv_load( meta, headers, fields )
    self[*headers.zip(fields).to_a.flatten.map { |e| eval(e) }]
  end
  
  def csv_headers
    keys.map { |key| key.inspect }
  end
  
  def csv_dump( headers )
    headers.map { |header| fetch(eval(header)).inspect }
  end
end

class TestSerialization < Test::Unit::TestCase
  
  ### Classes Used to Test Serialization ###
  
  class ReadOnlyName
    def initialize( first, last )
      @first, @last = first, last
    end

    attr_reader :first, :last
    
    def ==( other )
      %w{first last}.all? { |att| send(att) == other.send(att) }
    end
  end

  Name = Struct.new(:first, :last)
  
  class FullName < Name
    def initialize( first, last, suffix = nil )
      super(first, last)
      
      @suffix = suffix
    end
    
    attr_accessor :suffix
    
    def ==( other )
      %w{first last suffix}.all? { |att| send(att) == other.send(att) }
    end
  end
  
  ### Tests ###

  def test_class_dump
    @names = [ %w{James Gray},
              %w{Dana Gray},
              %w{Greg Brown} ].map do |first, last|
      ReadOnlyName.new(first, last)
    end
    
    assert_nothing_raised(Exception) do 
      @data = CSV.dump(@names)
    end
    assert_equal(<<-END_CLASS_DUMP.gsub(/^\s*/, ""), @data)
    class,TestSerialization::ReadOnlyName
    @first,@last
    James,Gray
    Dana,Gray
    Greg,Brown
    END_CLASS_DUMP
  end
  
  def test_struct_dump
    @names = [ %w{James Gray},
              %w{Dana Gray},
              %w{Greg Brown} ].map do |first, last|
      Name.new(first, last)
    end
    
    assert_nothing_raised(Exception) do 
      @data = CSV.dump(@names)
    end
    assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
    class,TestSerialization::Name
    first=,last=
    James,Gray
    Dana,Gray
    Greg,Brown
    END_STRUCT_DUMP
  end
  
  def test_inherited_struct_dump
    @names = [ %w{James Gray II},
              %w{Dana Gray},
              %w{Greg Brown} ].map do |first, last, suffix|
      FullName.new(first, last, suffix)
    end
    
    assert_nothing_raised(Exception) do 
      @data = CSV.dump(@names)
    end
    assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
    class,TestSerialization::FullName
    @suffix,first=,last=
    II,James,Gray
    ,Dana,Gray
    ,Greg,Brown
    END_STRUCT_DUMP
  end
  
  def test_load
    %w{ test_class_dump
        test_struct_dump
        test_inherited_struct_dump }.each do |test|
      send(test)
      CSV.load(@data).each do |loaded|
        assert_instance_of(@names.first.class, loaded)
        assert_equal(@names.shift, loaded)
      end
    end
  end
  
  def test_io
    test_class_dump
    
    data_file = File.join(File.dirname(__FILE__), "temp_test_data.csv")
    CSV.dump(@names, File.open(data_file, "w"))
    
    assert(File.exist?(data_file))
    assert_equal(<<-END_IO_DUMP.gsub(/^\s*/, ""), File.read(data_file))
    class,TestSerialization::ReadOnlyName
    @first,@last
    James,Gray
    Dana,Gray
    Greg,Brown
    END_IO_DUMP
    
    assert_equal(@names, CSV.load(File.open(data_file)))
    
    File.unlink(data_file)
  end
  
  def test_custom_dump_and_load
    obj = {1 => "simple", test: Hash}
    assert_equal(obj, CSV.load(CSV.dump([obj])).first)
  end
end