1 //metadoc LZOEncoder copyright Steve Dekorte, 2004
2 //metadoc LZOEncoder license BSD revised
3 //metadoc LZOEncoder category Compression
4 /*metadoc LZOEncoder description
5 ""The LZO object can be used to Z compress and uncompress data.
10 bf inputBuffer appendSeq("this is a message")
13 bf outputBuffer // this contains the encoded data
17 #include "IoLZOEncoder.h"
22 #define DATA(self) ((IoLZOData *)(IoObject_dataPointer(self)))
24 IoTag
*IoLZOEncoder_newTag(void *state
)
26 IoTag
*tag
= IoTag_newWithName_("LZOEncoder");
27 IoTag_state_(tag
, state
);
28 IoTag_freeFunc_(tag
, (IoTagFreeFunc
*)IoLZOEncoder_free
);
29 IoTag_cloneFunc_(tag
, (IoTagCloneFunc
*)IoLZOEncoder_rawClone
);
33 IoLZOEncoder
*IoLZOEncoder_proto(void *state
)
35 IoLZOEncoder
*self
= IoObject_new(state
);
36 IoObject_tag_(self
, IoLZOEncoder_newTag(state
));
38 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoLZOData
)));
40 IoState_registerProtoWithFunc_(state
, self
, IoLZOEncoder_proto
);
43 IoMethodTable methodTable
[] = {
44 {"beginProcessing", IoLZOEncoder_beginProcessing
},
45 {"process", IoLZOEncoder_process
},
46 {"endProcessing", IoLZOEncoder_endProcessing
},
49 IoObject_addMethodTable_(self
, methodTable
);
55 IoLZOEncoder
*IoLZOEncoder_rawClone(IoLZOEncoder
*proto
)
57 IoObject
*self
= IoObject_rawClonePrimitive(proto
);
58 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoLZOData
)));
62 IoLZOEncoder
*IoLZOEncoder_new(void *state
)
64 IoObject
*proto
= IoState_protoWithInitFunction_(state
, IoLZOEncoder_proto
);
65 return IOCLONE(proto
);
68 void IoLZOEncoder_free(IoLZOEncoder
*self
)
73 // ----------------------------------------------------------- *
75 IoObject
*IoLZOEncoder_beginProcessing(IoLZOEncoder
*self
, IoObject
*locals
, IoMessage
*m
)
77 /*doc LZOEncoder beginProcessing
78 Initializes the algorithm.
81 IOASSERT(lzo_init() == LZO_E_OK
, "Failed to init lzo");
82 DATA(self
)->isDone
= 0;
86 IoObject
*IoLZOEncoder_endProcessing(IoLZOEncoder
*self
, IoObject
*locals
, IoMessage
*m
)
88 /*doc LZOEncoder endProcessing
89 Finish processing remaining bytes of inputBuffer.
92 IoLZOEncoder_process(self
, locals
, m
); // process the full blocks first
93 DATA(self
)->isDone
= 1;
97 // --------------------------------------------------------------------
99 IoObject
*IoLZOEncoder_process(IoLZOEncoder
*self
, IoObject
*locals
, IoMessage
*m
)
101 /*doc LZOEncoder process
102 Process the inputBuffer and appends the result to the outputBuffer.
103 The processed inputBuffer is empties except for the spare bytes at
104 the end which don't fit into a cipher block.
107 lzo_align_t __LZO_MMODEL
*wrkmem
= DATA(self
)->wrkmem
;
109 UArray
*input
= IoObject_rawGetMutableUArraySlot(self
, locals
, m
, IOSYMBOL("inputBuffer"));
110 UArray
*output
= IoObject_rawGetMutableUArraySlot(self
, locals
, m
, IOSYMBOL("outputBuffer"));
112 unsigned char *inputBytes
= (uint8_t *)UArray_bytes(input
);
113 size_t inputSize
= UArray_sizeInBytes(input
);
118 size_t oldOutputSize
= UArray_size(output
);
119 lzo_uint outputRoom
= (inputSize
+ inputSize
/ 64 + 16 + 3);
120 unsigned char *outputBytes
;
122 UArray_setSize_(output
, oldOutputSize
+ outputRoom
);
123 outputBytes
= (uint8_t *)UArray_bytes(output
) + oldOutputSize
;
125 r
= lzo1x_1_compress(inputBytes
, inputSize
, outputBytes
, &outputRoom
, wrkmem
);
126 // r = lzo1x_decompress(in, in_len, out, &out_len, wrkmem);
130 IoState_error_(IOSTATE
, m
, "LZO compression failed: %d", r
);
134 UArray_setSize_(output
, oldOutputSize
+ outputRoom
);
135 UArray_setSize_(input
, 0);