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