// Copyright 2004-2014 Jim Voris
//
// 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 com.qumasoft.qvcslib;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Serializable;
/**
* The constant size portion of the QVCS archive header. This appears at the start of every QVCS archive file. Most of the elements are represented using {@link CommonShort}
* instances. This is for historical reasons for compatibility with the C++ version of QVCS, and to make it easy to support a platform neutral way of marshalling these
* objects when communicating with a non-Java client. These days, we only have Java based clients, but haven't taken the time to re-factor this code to take advantage of that.
* @author Jim Voris
*/
public final class LogFileHeader implements Serializable {
private static final long serialVersionUID = 6195018363104659070L;
private static final int QVCS_ARCHIVE_VERSION = 6;
/** The QVCSVersion. This is defines the version of the structure of the archive file. It should be a 6. */
private CommonShort iQVCSVersion = new CommonShort(); // QVCS Version
/** The Major Number. This is the major number of the default revision. */
private CommonShort iMajorNumber = new CommonShort(); // Major revision number of trunk
/** The Minor Number. This is the minor number of the default revision. */
private CommonShort iMinorNumber = new CommonShort(); // Minor revision number of trunk
/** The QVCS archive attributes. */
private CommonShort iAttributes = new CommonShort(); // Attributes for this log file
/** The number of versions (a.k.a. labels) that have been applied to this archive */
private CommonShort iVersionCount = new CommonShort(); // Number of version stamps
/** The number of revisions in this archive file */
private CommonShort iRevisionCount = new CommonShort(); // Number of revisions here
/** The default depth of this archive. A depth of 0 implies that the default branch for this file is the trunk. */
private CommonShort iDefaultDepth = new CommonShort(); // Depth of default branch (0 implies trunk)
/** The number of revisions that are locked in this archive file. */
private CommonShort iLockCount = new CommonShort(); // Number of locks on the logfile
/** The number of bytes to reserve for the file's access list. */
private CommonShort iAccessSize = new CommonShort(); // Strlen of Access list string including NULL
/** The number of bytes to reserve for the file's modifier list. */
private CommonShort iModifierSize = new CommonShort(); // Strlen of Modifier list string including NULL
/** The number of bytes to reserve for this file's comment prefix. */
private CommonShort iCommentSize = new CommonShort(); // Strlen of comment prefix string including NULL
/** The number of bytes to reserve for the owner's user name. */
private CommonShort iOwnerSize = new CommonShort(); // Strlen of Owner string including NULL
/** The number of bytes to reserve for the module description. */
private CommonShort iDescSize = new CommonShort(); // Strlen of Module desc including NULL
/** The number of bytes to reserve for the supplemental information section. */
private CommonShort iSupplementalInfoSize = new CommonShort(); // Length of the supplemental info section
/** The header checksum. */
private CommonShort iCheckSum = new CommonShort(); // Header checksum word
/** The archive attributes. Note that this member variable is not serialized to disk, as it is an alternate representation of the iAttributes data element. */
private ArchiveAttributes attributes;
/**
* Default constructor.
*/
public LogFileHeader() {
iQVCSVersion.setValue((short) QVCS_ARCHIVE_VERSION);
iMajorNumber.setValue((short) 0);
iMinorNumber.setValue((short) 0);
iAttributes.setValue((short) 0);
iVersionCount.setValue((short) 0);
iRevisionCount.setValue((short) 0);
iDefaultDepth.setValue((short) 0);
iLockCount.setValue((short) 0);
iAccessSize.setValue((short) 0);
iModifierSize.setValue((short) 0);
iCommentSize.setValue((short) 0);
iOwnerSize.setValue((short) 0);
iDescSize.setValue((short) 0);
iSupplementalInfoSize.setValue((short) 0);
iCheckSum.setValue(computeCheckSum());
}
/**
* Get the QVCSVersion. This is defines the version of the structure of the archive file. It should be a 6.
* @return the version of this archive file.
*/
public short qvcsVersion() {
return (short) iQVCSVersion.getValue();
}
/**
* Get the Major Number. This is the major number of the default revision.
* @return the MajorNumber. This is the major number of the default revision.
*/
public short majorNumber() {
return (short) iMajorNumber.getValue();
}
/**
* Set the Major Number. This is the major number of the default revision.
* @param number the MajorNumber. This is the major number of the default revision.
*/
public void setMajorNumber(int number) {
iMajorNumber.setValue(number);
}
/**
* Get the Minor Number. This is the minor number of the default revision.
* @return the Minor Number. This is the minor number of the default revision.
*/
public short minorNumber() {
return (short) iMinorNumber.getValue();
}
/**
* Increment the minor number.
*/
public void incrementMinorNumber() {
iMinorNumber.setValue(iMinorNumber.getValue() + 1);
}
/**
* Set the minor number.
* @param number the minor number.
*/
public void setMinorNumber(int number) {
iMinorNumber.setValue(number);
}
/**
* Get the QVCS archive attributes.
* @return the QVCS archive attributes.
*/
public ArchiveAttributes attributes() {
return attributes;
}
/**
* Get the version count. (a.k.a. the label count)... i.e. the number of labels that have been applied to this archive.
* @return the version count.
*/
public short versionCount() {
return (short) iVersionCount.getValue();
}
/**
* Set the version count.
* @param count the number of labels applied to this archive.
*/
public void setVersionCount(int count) {
iVersionCount.setValue(count);
}
/**
* Get the revision count.
* @return the revision count.
*/
public short revisionCount() {
return (short) iRevisionCount.getValue();
}
/**
* Increment the revision count.
*/
public void incrementRevisionCount() {
short revisionCount = (short) iRevisionCount.getValue();
revisionCount++;
iRevisionCount.setValue(revisionCount);
}
/**
* Get the default depth. If the default branch is the trunk, this will be 0; if the default branch is not the trunk, then this will be non-zero.
* @return the default depth.
*/
public short defaultDepth() {
return (short) iDefaultDepth.getValue();
}
/**
* Get the lock count.
* @return the number of locked revisions in this archive.
*/
public short lockCount() {
return (short) iLockCount.getValue();
}
/**
* Increment the lock count.
*/
public void incrementLockCount() {
iLockCount.setValue(1 + iLockCount.getValue());
}
/**
* Decrement the lock count.
*/
public void decrementLockCount() {
int lockCount = iLockCount.getValue();
if (lockCount > 0) {
lockCount--;
}
iLockCount.setValue(lockCount);
}
/**
* Get the size of the access list (in bytes).
* @return the size of the access list.
*/
public short accessSize() {
return (short) iAccessSize.getValue();
}
/**
* Get the size of the modifier list (in bytes).
* @return the size of the modifier list.
*/
public short modifierSize() {
return (short) iModifierSize.getValue();
}
/**
* Get the size of the comment prefix (in bytes).
* @return the size of the comment prefix.
*/
public short commentSize() {
return (short) iCommentSize.getValue();
}
/**
* Get the owner size (in bytes).
* @return the owner size.
*/
public short ownerSize() {
return (short) iOwnerSize.getValue();
}
/**
* Get the module description size (in bytes).
* @return the module description size.
*/
public short descriptionSize() {
return (short) iDescSize.getValue();
}
/**
* Get the supplementalInfo size (in bytes).
* @return the supplementalInfo size.
*/
public short supplementalInfoSize() {
return (short) iSupplementalInfoSize.getValue();
}
/**
* Get the header checkSum.
* @return the header checkSum.
*/
public short checkSum() {
return (short) iCheckSum.getValue();
}
/**
* Read the QVCS archive header from a stream. <b>This positions the stream to the beginning.</b>
* @param inStream the stream to read from.
* @return true if the read is successful; false otherwise.
* @throws com.qumasoft.qvcslib.LogFileReadException if the header checksum is bad.
*/
public boolean read(RandomAccessFile inStream) throws LogFileReadException {
boolean returnValue = true;
try {
// Make sure we start at the beginning of the file.
inStream.seek(0L);
// Read the version
iQVCSVersion.read(inStream);
// Read the major rev on the trunk
iMajorNumber.read(inStream);
// Read the minor rev on the trunk
iMinorNumber.read(inStream);
// Read the attributes
iAttributes.read(inStream);
// Create the associated archive attributes object
attributes = new ArchiveAttributes(iAttributes.getValue());
// Read the number of labels
iVersionCount.read(inStream);
// Read the number of revisions
iRevisionCount.read(inStream);
// Read the default depth
iDefaultDepth.read(inStream);
// Read the number of locks
iLockCount.read(inStream);
// Read the size of the access list
iAccessSize.read(inStream);
// Read the size of the modifier list
iModifierSize.read(inStream);
// Read the size of the comment prefix string
iCommentSize.read(inStream);
// Read the size of the owner string
iOwnerSize.read(inStream);
// Read the size of the module description
iDescSize.read(inStream);
// Read the size of the supplemental information
iSupplementalInfoSize.read(inStream);
// Read the header checksum
iCheckSum.read(inStream);
// Compare the checksum we read with the checksum we compute
if (iCheckSum.getValue() != computeCheckSum()) {
throw new LogFileReadException("Bad logfile checksum");
}
} catch (IOException ioProblem) {
returnValue = false;
}
return returnValue;
}
/**
* Write the QVCS archive header to a stream. <b>This positions the stream to the beginning.</b>
* @param outStream the stream to write to.
* @return true on success; false otherwise.
*/
public boolean write(RandomAccessFile outStream) {
boolean returnValue = true;
try {
// Make sure we start at the beginning of the file.
outStream.seek(0L);
// Write the version
iQVCSVersion.write(outStream);
// Write the major rev on the trunk
iMajorNumber.write(outStream);
// Write the minor rev on the trunk
iMinorNumber.write(outStream);
// Write the attributes
iAttributes.write(outStream);
// Write the number of labels
iVersionCount.write(outStream);
// Write the number of revisions
iRevisionCount.write(outStream);
// Write the default depth
iDefaultDepth.write(outStream);
// Write the number of locks
iLockCount.write(outStream);
// Write the size of the access list
iAccessSize.write(outStream);
// Write the size of the modifier list
iModifierSize.write(outStream);
// Write the size of the comment prefix string
iCommentSize.write(outStream);
// Write the size of the owner string
iOwnerSize.write(outStream);
// Write the size of the module description
iDescSize.write(outStream);
// Write the size of the supplemental information
iSupplementalInfoSize.write(outStream);
// Write the header checksum
iCheckSum.setValue(computeCheckSum());
iCheckSum.write(outStream);
} catch (IOException ioProblem) {
returnValue = false;
}
return returnValue;
}
/**
* Compute the checksum.
* @return the computed checksum.
*/
public short computeCheckSum() {
short checkSum;
checkSum = (short) (iAccessSize.getValue()
+ iAttributes.getValue()
+ iCommentSize.getValue()
+ iDefaultDepth.getValue()
+ iDescSize.getValue()
+ iLockCount.getValue()
+ iMajorNumber.getValue()
+ iMinorNumber.getValue()
+ iModifierSize.getValue()
+ iOwnerSize.getValue()
+ iQVCSVersion.getValue()
+ iRevisionCount.getValue()
+ iVersionCount.getValue()
+ iSupplementalInfoSize.getValue());
return checkSum;
}
/**
* Get the revision string of the newest trunk revision.
* @return the revision string of the newest trunk revision.
*/
public String latestTrunkRevision() {
String returnString = majorNumber() + "." + minorNumber();
return returnString;
}
/**
* Set the archive attributes.
* @param attribs the archive attributes.
*/
public void setAttributes(ArchiveAttributes attribs) {
this.attributes = new ArchiveAttributes(attribs);
iAttributes = new CommonShort(attribs.getAttributesAsInt());
}
/**
* Get the QVCS version.
* @return the QVCS version.
*/
public CommonShort getQVCSVersion() {
return iQVCSVersion;
}
/**
* Set the QVCS version.
* @param qvcsVersion the QVCS version.
*/
public void setQVCSVersion(CommonShort qvcsVersion) {
this.iQVCSVersion = qvcsVersion;
}
/**
* Get the major number.
* @return the major number.
*/
public CommonShort getMajorNumber() {
return iMajorNumber;
}
/**
* Set the major number.
* @param majorNumber the major number.
*/
public void setMajorNumber(CommonShort majorNumber) {
this.iMajorNumber = majorNumber;
}
/**
* Get the minor number.
* @return the minor number.
*/
public CommonShort getMinorNumber() {
return iMinorNumber;
}
/**
* Set the minor number.
* @param minorNumber the minor number.
*/
public void setMinorNumber(CommonShort minorNumber) {
this.iMinorNumber = minorNumber;
}
/**
* Get the attribute bits.
* @return the attribute bits.
*/
public CommonShort getAttributeBits() {
return iAttributes;
}
/**
* Set the attribute bits.
* @param attribs the attribute bits.
*/
public void setAttributeBits(CommonShort attribs) {
this.iAttributes = attribs;
}
/**
* Get the label count.
* @return the label count.
*/
public CommonShort getVersionCount() {
return iVersionCount;
}
/**
* Set the label count.
* @param versionCount the label count.
*/
public void setVersionCount(CommonShort versionCount) {
this.iVersionCount = versionCount;
}
/**
* Get the revision count.
* @return the revision count.
*/
public CommonShort getRevisionCount() {
return iRevisionCount;
}
/**
* Set the revision count.
* @param revisionCount the revision count.
*/
public void setRevisionCount(CommonShort revisionCount) {
this.iRevisionCount = revisionCount;
}
/**
* Get the default depth.
* @return the default depth.
*/
public CommonShort getDefaultDepth() {
return iDefaultDepth;
}
/**
* Set the default depth.
* @param defaultDepth the default depth.
*/
public void setDefaultDepth(CommonShort defaultDepth) {
this.iDefaultDepth = defaultDepth;
}
/**
* Get the lock count.
* @return the lock count.
*/
public CommonShort getLockCount() {
return iLockCount;
}
/**
* Set the lock count.
* @param lockCount the lock count.
*/
public void setLockCount(CommonShort lockCount) {
this.iLockCount = lockCount;
}
/**
* Get the access list size.
* @return the access list size.
*/
public CommonShort getAccessSize() {
return iAccessSize;
}
/**
* Set the access list size.
* @param accessSize the access list size.
*/
public void setAccessSize(CommonShort accessSize) {
this.iAccessSize = accessSize;
}
/**
* Get the modifier list size.
* @return the modifier list size.
*/
public CommonShort getModifierSize() {
return iModifierSize;
}
/**
* Set the modifier list size.
* @param modifierSize the modifier list size.
*/
public void setModifierSize(CommonShort modifierSize) {
this.iModifierSize = modifierSize;
}
/**
* Get the comment prefix size.
* @return the comment prefix size.
*/
public CommonShort getCommentSize() {
return iCommentSize;
}
/**
* Set the comment prefix size.
* @param commentSize the comment prefix size.
*/
public void setCommentSize(CommonShort commentSize) {
this.iCommentSize = commentSize;
}
/**
* Get the owner size.
* @return the owner size.
*/
public CommonShort getOwnerSize() {
return iOwnerSize;
}
/**
* Set the owner size.
* @param ownerSize the owner size.
*/
public void setOwnerSize(CommonShort ownerSize) {
this.iOwnerSize = ownerSize;
}
/**
* Get the module description size.
* @return the module description size.
*/
public CommonShort getDescSize() {
return iDescSize;
}
/**
* Set the module description size.
* @param descSize the module description size.
*/
public void setDescSize(CommonShort descSize) {
this.iDescSize = descSize;
}
/**
* Get the size of the supplemental information.
* @return the size of the supplemental information.
*/
public CommonShort getSupplementalInfoSize() {
return iSupplementalInfoSize;
}
/**
* Set the size of the supplemental information.
* @param supplementalInfoSize the size of the supplemental information.
*/
public void setSupplementalInfoSize(CommonShort supplementalInfoSize) {
this.iSupplementalInfoSize = supplementalInfoSize;
}
/**
* Get the header checksum.
* @return the header checksum.
*/
public CommonShort getCheckSum() {
return iCheckSum;
}
/**
* Set the header checksum.
* @param checkSum the header checksum.
*/
public void setCheckSum(CommonShort checkSum) {
this.iCheckSum = checkSum;
}
/**
* Get the QVCS archive attributes.
* @return the QVCS archive attributes.
*/
public ArchiveAttributes getAttributes() {
return attributes;
}
}