summaryrefslogtreecommitdiff
path: root/source4/librpc/ndr
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-08-20 22:12:51 +0200
committerStefan Metzmacher <metze@samba.org>2008-09-07 19:20:41 +0200
commit1efff73068e933dd0b4cc81ff901f6010fda9a6b (patch)
tree80470a6e6f8953d30b0bba60daa8a75f00a8e6d9 /source4/librpc/ndr
parent008c9a68874026989d286e4a06a3a4f2f0e32605 (diff)
downloadsamba-1efff73068e933dd0b4cc81ff901f6010fda9a6b.tar.gz
samba-1efff73068e933dd0b4cc81ff901f6010fda9a6b.tar.bz2
samba-1efff73068e933dd0b4cc81ff901f6010fda9a6b.zip
ndr_compression: add XPRESS compression support
metze (This used to be commit 1432a96d37e367d9d97d48b69c6f16351a9ad066)
Diffstat (limited to 'source4/librpc/ndr')
-rw-r--r--source4/librpc/ndr/ndr_compression.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/source4/librpc/ndr/ndr_compression.c b/source4/librpc/ndr/ndr_compression.c
index aa9f907eed..92c5b049df 100644
--- a/source4/librpc/ndr/ndr_compression.c
+++ b/source4/librpc/ndr/ndr_compression.c
@@ -323,7 +323,55 @@ static enum ndr_err_code ndr_push_compression_xpress_chunk(struct ndr_push *ndrp
struct ndr_pull *ndrpull,
bool *last)
{
- return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION, "XPRESS compression is not supported yet (PUSH)");
+ DATA_BLOB comp_chunk;
+ uint32_t comp_chunk_size_offset;
+ DATA_BLOB plain_chunk;
+ uint32_t plain_chunk_size;
+ uint32_t plain_chunk_offset;
+ uint32_t max_plain_size = 0x00010000;
+ uint32_t max_comp_size = 0x00020000 + 2; /* TODO: use the correct value here */
+ uint32_t tmp_offset;
+ ssize_t ret;
+
+ plain_chunk_size = MIN(max_plain_size, ndrpull->data_size - ndrpull->offset);
+ plain_chunk_offset = ndrpull->offset;
+ NDR_CHECK(ndr_pull_advance(ndrpull, plain_chunk_size));
+
+ plain_chunk.data = ndrpull->data + plain_chunk_offset;
+ plain_chunk.length = plain_chunk_size;
+
+ if (plain_chunk_size < max_plain_size) {
+ *last = true;
+ }
+
+ NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, plain_chunk_size));
+ comp_chunk_size_offset = ndrpush->offset;
+ NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, 0xFEFEFEFE));
+
+ NDR_CHECK(ndr_push_expand(ndrpush, max_comp_size));
+
+ comp_chunk.data = ndrpush->data + ndrpush->offset;
+ comp_chunk.length = max_comp_size;
+
+ /* Compressing the buffer using LZ Xpress algorithm */
+ ret = lzxpress_compress(plain_chunk.data,
+ plain_chunk.length,
+ comp_chunk.data,
+ comp_chunk.length);
+ if (ret < 0) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "XPRESS lzxpress_compress() returned %d\n",
+ ret);
+ }
+ comp_chunk.length = ret;
+
+ tmp_offset = ndrpush->offset;
+ ndrpush->offset = comp_chunk_size_offset;
+ NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, comp_chunk.length));
+ ndrpush->offset = tmp_offset;
+
+ ndrpush->offset += comp_chunk.length;
+ return NDR_ERR_SUCCESS;
}
/*