content: /*
   * Copyright (C) 2014 Alex
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  package com.alexhulbert.icewind.autocol;
  
  import com.alexhulbert.icewind.LoadingBar;
  import com.google.protobuf.GeneratedMessage;
  import com.google.protobuf.InvalidProtocolBufferException;
  import com.google.protobuf.Parser;
  import java.io.ByteArrayInputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   *
   * @author Alex
   */
  public class EasyProto<T extends GeneratedMessage> {
      private final byte[] inp;
      private final Parser p;
      
      protected EasyProto(Parser<T> parser, byte[] input) {
          inp = input;
          p   = parser;
      }
      
      /**
       * Decode a single, protobuf-encoded Message
       * @return a decoded instance of type T
       * @throws InvalidProtocolBufferException Doesn't fit the protobuf
       */
      public T parse() throws InvalidProtocolBufferException {
          return (T) p.parseFrom(inp);
      }
      
      /**
       * Parse and decode a varint-delimited, protobuf-encoded Message array
       * @return An array of T messages
       */
      public List<T> parseVarint() {
          ByteArrayInputStream bais = new ByteArrayInputStream(inp);
          List<T> lst = new ArrayList<T>();
          while (bais.available() > 0) {
              try {
                  lst.add((T) p.parseDelimitedFrom(bais));
              } catch (InvalidProtocolBufferException ex) {
                  //TODO: Fix this
                  ex.printStackTrace();
              }
          }
          
          return lst;
      }
      
      /**
       * How many varint-encoded messages are contained within the input
       * @return The number of messages
       */
      public long size() {
          long s = 0;
          ByteArrayInputStream bais = new ByteArrayInputStream(inp);
          while (bais.available() > 0) {
              try {
                  p.parseDelimitedFrom(bais);
                  s++;
              } catch (InvalidProtocolBufferException ex) {
                  ex.printStackTrace(); //TODO: Fix this
              }
          }
          return s;
      }
      
      /**
       * This is a little slower, but you can use it with those pretty progress bars. No more boring throbbers!
       * @param lb The LoadingBar instance to write to
       * @param loadText The prefixed
       * @return An array of T messages
       */
      public List<T> parseVarint(LoadingBar lb, String loadText) {
          ByteArrayInputStream counter = new ByteArrayInputStream(inp);
          ByteArrayInputStream parser  = new ByteArrayInputStream(inp); //Pass-by-reference
          long totalCount = 0;
          List<T> output = new ArrayList<T>();
          while (counter.available() > 0) {
              try {
                  p.parseDelimitedFrom(counter);
                  totalCount++;
              } catch (InvalidProtocolBufferException ex) {}
          }
          
          for (int i = 0; i < totalCount; i++) {
              try {
                  output.add((T) p.parseDelimitedFrom(parser));
                  lb.progress((i*100)/totalCount);
                  lb.status(loadText + String.format(" (%s/%s)", i, totalCount));
              } catch (InvalidProtocolBufferException ex) {
                  ex.printStackTrace(); //TODO: Fix this
              }
          }
          return output;
      }
  }
  