view usr/src/cmd/audio/utilities/AudioRawPipe.cc @ 4:1a15d5aaf794

synchronized with onnv_86 (6202) in onnv-gate
author Koji Uno <koji.uno@sun.com>
date Mon, 31 Aug 2009 14:38:03 +0900
parents c9caec207d52
children
line wrap: on
line source

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 1991-2003 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

#include <AudioRawPipe.h>
#include <libaudio.h>
#include <audio_hdr.h>

// class AudioPipe methods

// Constructor with file descriptor, mode, and optional name
AudioRawPipe::
AudioRawPipe(
	const int		desc,		// file descriptor
	const FileAccess	acc,		// access mode
	const AudioHdr&		hdr_local,	// header
	const char		*name_local,	// name
	const off_t		off		// offset
):AudioPipe(desc, acc, name_local), offset(off)
{
	isopened = FALSE;
	setfd(desc);
	SetHeader(hdr_local);
}

// The create routine for pipes writes a file header
AudioError AudioRawPipe::
Create()
{
	AudioError	err;

	// Was the header properly set?
	err = GetHeader().Validate();
	if (err != AUDIO_SUCCESS)
		return (RaiseError(err));

	// Open fd supplied by constructor
	if (!isfdset() || opened()) {
		return (RaiseError(AUDIO_ERR_NOEFFECT, Warning));
	}

	// set flag for opened() test
	isopened = TRUE;

	// Set the actual output length to zero
	setlength(0.);

	return (AUDIO_SUCCESS);
}

// The open routine for raw pipes validates the header and
// init's the read pos to offset and sets the opened flag.
AudioError AudioRawPipe::
Open()
{
	AudioError	err;
	struct stat	st;

	// The constructor should have supplied a valid fd
	// If fd is not open, or file header already decoded, skip it
	if (!isfdset() || opened())
		return (RaiseError(AUDIO_ERR_NOEFFECT, Warning));

	// Stat the file, to see if it is a regular file
	if (fstat(getfd(), &st) < 0)
		return (RaiseError(AUDIO_UNIXERROR));

	// check validity of file header
	err = GetHeader().Validate();
	if (err != AUDIO_SUCCESS) {
		(void) close(getfd());
		setfd(-1);
		return (err);
	}

	// Only trust the file size for regular files
	if (S_ISREG(st.st_mode)) {
		// for raw files - no hdr, so it's the whole file minus
		// the offset.
		setlength(GetHeader().Bytes_to_Time(st.st_size - offset));
	} else {
		// don't know ...
		setlength(AUDIO_UNKNOWN_TIME);
	}

	// set flag for opened() test
	isopened = TRUE;

	err = SetOffset(offset);

	// reset logical position to 0.0, since this is, in effect,
	// the beginning of the file.
	SetReadPosition(0.0, Absolute);

	return (err);
}

Boolean AudioRawPipe::
opened() const
{
	return (isopened);
}

AudioError AudioRawPipe::
SetOffset(off_t val)
{
	off_t		setting = 0;
	AudioError	err;

	// only read only files for now
	if (GetAccess().Writeable()) {
		return (AUDIO_ERR_NOEFFECT);
	}

	// only allow this if we haven't read anything yet (i.e. current
	// position is 0).
	if (ReadPosition() != 0.) {
		return (AUDIO_ERR_NOEFFECT);
	}

	if ((err = seekread(GetHeader().Bytes_to_Time(val), setting))
	    != AUDIO_SUCCESS) {
		return (err);
	}

	// this should *never* happen 'cause seekread just sets setting
	// to GetHeader().Time_to_Bytes....
	if (setting != val) {
		// don't really know what error is apropos for this.
		return (AUDIO_ERR_BADFRAME);
	}

	offset = val;
	return (AUDIO_SUCCESS);
}

off_t AudioRawPipe::
GetOffset() const
{
	return (offset);
}