001 /*
002 * This file is part of muCommander, http://www.mucommander.com
003 * Copyright (C) 2002-2008 Maxence Bernard
004 *
005 * muCommander is free software; you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation; either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * muCommander is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 */
018
019
020 package com.mucommander.io;
021
022
023 /**
024 * Contains a number of bytes which have been read/written from/to a {@link CounterInputStream}/{@link CounterOutputStream}.
025 *
026 * <p>Provided methods allow to read the the byte count, add a number bytes to it or reset it (make it zero).
027 *
028 * <p>This class is thread safe, ensuring that the counter is always in a consistent state.</p>
029 *
030 * @see com.mucommander.io.CounterInputStream
031 * @see com.mucommander.io.CounterOutputStream
032 * @author Maxence Bernard
033 */
034 public class ByteCounter {
035
036 /** Byte count */
037 private long count;
038
039 /** Byte counter to add to the value returned by {@link #getByteCount()} */
040 private ByteCounter addedCounter;
041
042
043 /**
044 * Creates a new ByteCounter with an initial byte count equal to zero.
045 */
046 public ByteCounter() {
047 }
048
049 /**
050 * Creates a new ByteCounter with an initial byte count equal to zero and using the given ByteCounter.
051 *
052 * <p>The value returned by {@link #getByteCount()} will be the sum of the internal byte count and the one from
053 * the specified ByteCounter, as returned by its {@link #getByteCount()} method. Resetting this ByteCounter's value
054 * will only affect the internal byte count and not the one from the specified ByteCounter.
055 */
056 public ByteCounter(ByteCounter counter) {
057 this.addedCounter = counter;
058 }
059
060
061 /**
062 * Return the number of bytes which have been accounted for.
063 */
064 public synchronized long getByteCount() {
065 if(addedCounter!=null)
066 return count + addedCounter.getByteCount();
067
068 return this.count;
069 }
070
071
072 /**
073 * Increases the byte counter by the provided number of bytes. If the specified number is negative,
074 * the byte counter will be left unchanged (won't be decreased).
075 *
076 * @param nbBytes number of bytes to add to the byte counter, will be ignored if negative
077 */
078 public synchronized void add(long nbBytes) {
079 if(nbBytes>0)
080 this.count += nbBytes;
081 }
082
083
084 /**
085 * Increases the byte counter by the number of bytes contained in the specified counter (as returned by its
086 * {@link #getByteCount()} method) and resets its byte counter after (if specified).
087 *
088 * @param counter the Bytecounter to add to this one, and reset after (if specified).
089 * @param resetAfter if true, the specified counter will be reset after its byte count has been added to this ByteCounter
090 */
091 public synchronized void add(ByteCounter counter, boolean resetAfter) {
092 // Hold a lock on the provided counter to make sure that it is not modified or accessed
093 // while this operation is carried out
094 synchronized(counter) {
095 add(counter.getByteCount());
096 if(resetAfter)
097 counter.reset();
098 }
099 }
100
101
102 /**
103 * Resets the byte counter (make it zero).
104 */
105 public synchronized void reset() {
106 this.count = 0;
107 }
108 }