001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.fusesource.hawtbuf.proto;
018
019 import java.io.IOException;
020
021 import org.fusesource.hawtbuf.Buffer;
022
023
024 abstract public class DeferredDecodeMessage<T> extends BaseMessage<T> {
025
026 protected Buffer encodedForm;
027 protected boolean decoded = true;
028
029 @Override
030 public T mergeFramed(CodedInputStream input) throws IOException {
031 int length = input.readRawVarint32();
032 int oldLimit = input.pushLimit(length);
033 T rc = mergeUnframed(input.readRawBytes(length));
034 input.popLimit(oldLimit);
035 return rc;
036 }
037
038 @SuppressWarnings("unchecked")
039 @Override
040 public T mergeUnframed(Buffer data) throws InvalidProtocolBufferException {
041 encodedForm = data;
042 decoded = false;
043 return (T) this;
044 }
045
046 @Override
047 public Buffer toUnframedBuffer() {
048 if (encodedForm == null) {
049 encodedForm = super.toUnframedBuffer();
050 }
051 return encodedForm;
052 }
053
054 protected void load() {
055 if (!decoded) {
056 decoded = true;
057 try {
058 Buffer originalForm = encodedForm;
059 encodedForm=null;
060 CodedInputStream input = new CodedInputStream(originalForm);
061 mergeUnframed(input);
062 input.checkLastTagWas(0);
063 // We need to reset the encoded form because the mergeUnframed
064 // from a stream clears it out.
065 encodedForm = originalForm;
066 checktInitialized();
067 } catch (Throwable e) {
068 throw new RuntimeException("Deferred message decoding failed: " + e.getMessage(), e);
069 }
070 }
071 }
072
073 protected void loadAndClear() {
074 super.loadAndClear();
075 load();
076 encodedForm = null;
077 }
078
079 public void clear() {
080 super.clear();
081 encodedForm = null;
082 decoded = true;
083 }
084
085 public boolean isDecoded() {
086 return decoded;
087 }
088
089 public boolean isEncoded() {
090 return encodedForm != null;
091 }
092
093 }