/*
* Copyright (C) 2006-2008 Alfresco Software Limited.
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.jlan.smb.dcerpc;
import java.util.Vector;
/**
* DCE/RPC List Class
*
* <p>Base class for lists of objects that are DCE/RPC readable and/or writeable.
*
* @author gkspencer
*/
public abstract class DCEList {
// Information level
private int m_infoLevel;
// List of DCE/RPC readable/writeable objects
private Vector m_dceObjects;
/**
* Default constructor
*/
protected DCEList() {
m_dceObjects = new Vector();
}
/**
* Class constructor
*
* @param infoLevel int
*/
protected DCEList(int infoLevel) {
m_dceObjects = new Vector();
m_infoLevel = infoLevel;
}
/**
* Class constructor
*
* @param buf DCEBuffer
* @exception DCEBufferException
*/
protected DCEList(DCEBuffer buf)
throws DCEBufferException {
// Read the header from the DCE/RPC buffer that contains the information level and container pointer
m_infoLevel = buf.getInt();
buf.skipBytes(4);
if ( buf.getPointer() != 0) {
// Indicate that the container is valid
m_dceObjects = new Vector();
}
else {
// Container is not valid, no more data to follow
m_dceObjects = null;
}
}
/**
* Return the information level
*
* @return int
*/
public final int getInformationLevel() {
return m_infoLevel;
}
/**
* Return the number of entries in the list
*
* @return int
*/
public final int numberOfEntries() {
return m_dceObjects != null ? m_dceObjects.size() : 0;
}
/**
* Return the object list
*
* @return Vector
*/
public final Vector getList() {
return m_dceObjects;
}
/**
* Return an element from the list
*
* @param idx int
* @return Object
*/
public final Object getElement(int idx) {
// Range check the index
if ( m_dceObjects == null || idx < 0 || idx >= m_dceObjects.size())
return null;
// Return the object
return m_dceObjects.elementAt(idx);
}
/**
* Determine if the container is valid
*
* @return boolean
*/
protected final boolean containerIsValid() {
return m_dceObjects != null ? true : false;
}
/**
* Add an object to the list
*
* @param obj Object
*/
protected final void addObject(Object obj) {
m_dceObjects.addElement(obj);
}
/**
* Set the information level
*
* @param infoLevel int
*/
protected final void setInformationLevel(int infoLevel) {
m_infoLevel = infoLevel;
}
/**
* Set the object list
*
* @param list Vector
*/
protected final void setList(Vector list) {
m_dceObjects = list;
}
/**
* Get a new object for the list to fill in
*
* @return DCEReadable
*/
protected abstract DCEReadable getNewObject();
/**
* Read a list of objects from the DCE buffer
*
* @param buf DCEBuffer
* @throws DCEBufferException
*/
public void readList(DCEBuffer buf)
throws DCEBufferException {
// Check if the container is valid, if so the object list will be valid
if ( containerIsValid() == false)
return;
// Read the container object count and array pointer
int numEntries = buf.getInt();
if ( buf.getPointer() != 0) {
// Get the array element count
int elemCnt = buf.getInt();
if ( elemCnt > 0) {
// Read in the array elements
while ( elemCnt-- > 0) {
// Create a readable object and add to the list
DCEReadable element = getNewObject();
addObject(element);
// Load the main object details
element.readObject(buf);
}
// Load the strings for the readable information objects
for ( int i = 0; i < numberOfEntries(); i++) {
// Get a readable object
DCEReadable element = (DCEReadable) getList().elementAt(i);
// Load the strings for the readable object
element.readStrings(buf);
}
}
}
}
/**
* Write the list of objects to a DCE buffer
*
* @param buf DCEBuffer
* @exception DCEBufferException
*/
public final void writeList(DCEBuffer buf)
throws DCEBufferException {
// Pack the container header
buf.putInt(getInformationLevel());
buf.putInt(getInformationLevel());
// Check if the object list is valid
if ( m_dceObjects != null) {
// Add a pointer to the container and the number of objects
buf.putPointer(true);
buf.putInt(m_dceObjects.size());
// Add the pointer to the array of objects and number of objects
buf.putPointer(true);
buf.putInt(m_dceObjects.size());
// Create a seperate DCE buffer to build the string list which may follow the main
// object list, depending on the object
DCEBuffer strBuf = new DCEBuffer();
// Pack the object information
for ( int i = 0; i < m_dceObjects.size(); i++) {
// Get an object from the list
DCEWriteable object = (DCEWriteable) m_dceObjects.elementAt(i);
// Write the object to the buffer, strings may go into the seperate string buffer which will be appended
// to the main buffer after all the objects have been written
object.writeObject(buf, strBuf);
}
// If the string buffer has been used append it to the main buffer
buf.putBuffer(strBuf);
// Add the trailing list size
buf.putInt(m_dceObjects.size());
// Add the enum handle
buf.putInt(0);
}
else {
// Add an empty container/array
buf.putZeroInts(4);
}
}
/**
* Return the list as a string
*
* @return String
*/
public String toString() {
StringBuffer str = new StringBuffer();
str.append("[Level=");
str.append(getInformationLevel());
str.append(",Entries=");
str.append(numberOfEntries());
str.append(",Class=");
str.append(getNewObject().getClass().getName());
str.append("]");
return str.toString();
}
}