/* * Copyright (C) 2015 SoftIndex LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.datakernel.http; import io.datakernel.bytebuf.ByteBuf; import io.datakernel.bytebuf.ByteBufPool; import io.datakernel.exception.ParseException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; final class GzipProcessor { private GzipProcessor() { } static GzipProcessor create() { return new GzipProcessor(); } static ByteBuf fromGzip(ByteBuf raw) throws ParseException { assert raw.readRemaining() > 0; try (GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(raw.array(), raw.readPosition(), raw.readRemaining()))) { int nRead; ByteBuf data = ByteBufPool.allocate(256); while ((nRead = gzip.read(data.array(), data.writePosition(), data.writeRemaining())) != -1) { data.moveWritePosition(nRead); data = ByteBufPool.ensureTailRemaining(data, data.readRemaining()); } return data; } catch (IOException e) { throw new ParseException("Can't decode gzip", e); } finally { raw.recycle(); } } static ByteBuf toGzip(ByteBuf raw) { assert raw.readRemaining() > 0; try { ByteBufOutputStream out = new ByteBufOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(out); gzip.write(raw.array(), raw.readPosition(), raw.readRemaining()); gzip.close(); return out.getBuf(); } catch (IOException e) { throw new AssertionError(); } finally { raw.recycle(); } } private static class ByteBufOutputStream extends OutputStream { private ByteBuf buf = ByteBufPool.allocate(256); @Override public void write(int b) { buf = ByteBufPool.ensureTailRemaining(buf, 1); buf.put((byte) b); } @Override public void write(byte[] bytes) { write(bytes, 0, bytes.length); } @Override public void write(byte[] bytes, int off, int len) { buf = ByteBufPool.ensureTailRemaining(buf, len); buf.put(bytes, off, len); } public ByteBuf getBuf() { return buf; } } }