1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1990-2001 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <AudioPipe.h>
30 
31 // class AudioPipe methods
32 
33 
34 // Constructor with file descriptor, mode, and optional name
35 AudioPipe::
AudioPipe(const int desc,const FileAccess acc,const char * name_local)36 AudioPipe(
37 	const int		desc,		// file descriptor
38 	const FileAccess	acc,		// access mode
39 	const char		*name_local):	// name
40 	AudioUnixfile(name_local, acc)
41 {
42 	setfd(desc);
43 }
44 
45 // The create routine for pipes writes a file header
46 AudioError AudioPipe::
Create()47 Create()
48 {
49 	AudioError	err;
50 
51 	// Was the header properly set?
52 	err = GetHeader().Validate();
53 	if (err != AUDIO_SUCCESS)
54 		return (RaiseError(err));
55 
56 	// Open fd supplied by constructor
57 	if (!isfdset())
58 		return (RaiseError(AUDIO_ERR_NOEFFECT));
59 
60 	// Write the file header with current (usually unknown) size
61 	err = encode_filehdr();
62 	if (err != AUDIO_SUCCESS) {
63 		(void) close(getfd());		// If error, remove file
64 		setfd(-1);
65 		return (err);
66 	}
67 
68 	// Set the actual output length to zero
69 	setlength(0.);
70 
71 	return (AUDIO_SUCCESS);
72 }
73 
74 // The open routine for pipes decodes the header
75 AudioError AudioPipe::
Open()76 Open()
77 {
78 	AudioError		err;
79 
80 	// The constructor should have supplied a valid fd
81 	if (!isfdset())
82 		return (RaiseError(AUDIO_ERR_NOEFFECT));
83 
84 	// Decode a file header
85 	err = decode_filehdr();
86 	if (err != AUDIO_SUCCESS) {
87 		(void) close(getfd());
88 		setfd(-1);
89 		return (err);
90 	}
91 
92 	return (AUDIO_SUCCESS);
93 }
94 
95 // Read data from underlying pipe into specified buffer.
96 // No data format translation takes place.
97 // Since there's no going back, the object's read position pointer is updated.
98 AudioError AudioPipe::
ReadData(void * buf,size_t & len,Double & pos)99 ReadData(
100 	void*		buf,		// destination buffer address
101 	size_t&		len,		// buffer length (updated)
102 	Double&		pos)		// start position (updated)
103 {
104 	AudioError	err;
105 	char		*tbuf;		// current buffer pointer
106 	size_t		remain;		// number of bytes remaining
107 	size_t		cnt;		// accumulated number of bytes read
108 
109 	tbuf = (char *)buf;
110 	remain = len;
111 	cnt = 0;
112 
113 	// Pipes return short reads.  If non-blocking i/o, try to read all.
114 	do {
115 		// Call the real routine
116 		err = AudioUnixfile::ReadData((void*)tbuf, remain, pos);
117 
118 		// Update the object's read position
119 		if (!err) {
120 			(void) SetReadPosition(pos, Absolute);
121 			if (remain == 0)
122 				break;
123 			cnt += remain;
124 			tbuf += remain;
125 			remain = len - cnt;
126 		}
127 	} while (!err && (remain > 0) && GetBlocking());
128 	len = cnt;
129 	if (len > 0)
130 		return (AUDIO_SUCCESS);
131 	return (err);
132 }
133 
134 // Write data to underlying file from specified buffer.
135 // No data format translation takes place.
136 // Since there's no going back, the object's write position pointer is updated.
137 AudioError AudioPipe::
WriteData(void * buf,size_t & len,Double & pos)138 WriteData(
139 	void*		buf,		// source buffer address
140 	size_t&		len,		// buffer length (updated)
141 	Double&		pos)		// start position (updated)
142 {
143 	AudioError	err;
144 
145 	// Call the real routine
146 	err = AudioUnixfile::WriteData(buf, len, pos);
147 
148 	// Update the object's write position
149 	if (err == AUDIO_SUCCESS)
150 		(void) SetWritePosition(pos, Absolute);
151 	return (err);
152 }
153