Addons updated to new doc format
[io.git] / addons / LZO / source / IoLZOEncoder.c
blob0007a683d961e4f2e4ef7b15232a79bb8843085d
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.
6 Example use;
7 <code>
8 bf = LZO clone
9 bf beginProcessing
10 bf inputBuffer appendSeq("this is a message")
11 bf process
12 bf endProcess
13 bf outputBuffer // this contains the encoded data
14 </code>
17 #include "IoLZOEncoder.h"
18 #include "IoState.h"
19 #include "IoNumber.h"
20 #include "IoSeq.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);
30 return tag;
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},
47 {NULL, NULL},
49 IoObject_addMethodTable_(self, methodTable);
52 return self;
55 IoLZOEncoder *IoLZOEncoder_rawClone(IoLZOEncoder *proto)
57 IoObject *self = IoObject_rawClonePrimitive(proto);
58 IoObject_setDataPointer_(self, calloc(1, sizeof(IoLZOData)));
59 return self;
62 IoLZOEncoder *IoLZOEncoder_new(void *state)
64 IoObject *proto = IoState_protoWithInitFunction_(state, IoLZOEncoder_proto);
65 return IOCLONE(proto);
68 void IoLZOEncoder_free(IoLZOEncoder *self)
70 free(DATA(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;
83 return self;
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;
94 return self;
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);
115 if (inputSize)
117 int r;
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);
128 if (r != LZO_E_OK)
130 IoState_error_(IOSTATE, m, "LZO compression failed: %d", r);
134 UArray_setSize_(output, oldOutputSize + outputRoom);
135 UArray_setSize_(input, 0);
138 return self;