/*
* 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;
}
}