vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / media-add-ons / usb_webcam / CamDeframer.cpp
blob01ab6ad25fbea062ad88e7868e04285e48f12143
1 /*
2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
4 */
6 #define CD_COL "31"
7 #include "CamDeframer.h"
8 #include "CamDevice.h"
9 #include "CamDebug.h"
10 #include <Autolock.h>
11 #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN
12 #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES
15 CamDeframer::CamDeframer(CamDevice *device)
16 : CamFilterInterface(device),
17 fDevice(device),
18 fState(ST_SYNC),
19 fFrameSem(B_ERROR),
20 fLocker("CamDeframer Framelist lock", true),
21 fSOFTags(NULL),
22 fEOFTags(NULL),
23 fNumSOFTags(0),
24 fNumEOFTags(0),
25 fLenSOFTags(0),
26 fLenEOFTags(0),
27 fSkipSOFTags(0),
28 fSkipEOFTags(0)
30 fMinFrameSize = fDevice->MinRawFrameSize();
31 fMaxFrameSize = fDevice->MaxRawFrameSize();
32 fFrameSem = create_sem(0, "CamDeframer sem");
33 fCurrentFrame = AllocFrame();
37 CamDeframer::~CamDeframer()
39 delete_sem(fFrameSem);
40 BAutolock l(fLocker);
41 delete fCurrentFrame;
45 ssize_t
46 CamDeframer::Read(void *buffer, size_t size)
48 BAutolock l(fLocker);
49 CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
50 if (!f)
51 return EIO;
52 return f->Read(buffer, size);
56 ssize_t
57 CamDeframer::ReadAt(off_t pos, void *buffer, size_t size)
59 BAutolock l(fLocker);
60 CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
61 if (!f)
62 return EIO;
63 return f->ReadAt(pos, buffer, size);
67 off_t
68 CamDeframer::Seek(off_t position, uint32 seek_mode)
70 BAutolock l(fLocker);
71 CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
72 if (!f)
73 return EIO;
74 return f->Seek(position, seek_mode);
78 off_t
79 CamDeframer::Position() const
81 BAutolock l((BLocker &)fLocker); // need to get rid of const here
82 CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
83 if (!f)
84 return EIO;
85 return f->Position();
89 status_t
90 CamDeframer::SetSize(off_t size)
92 (void)size;
93 return EINVAL;
97 ssize_t
98 CamDeframer::Write(const void *buffer, size_t size)
100 (void)buffer;
101 (void)size;
102 return EINVAL;
106 ssize_t
107 CamDeframer::WriteAt(off_t pos, const void *buffer, size_t size)
109 (void)pos;
110 (void)buffer;
111 (void)size;
112 return EINVAL;
116 status_t
117 CamDeframer::WaitFrame(bigtime_t timeout)
119 return acquire_sem_etc(fFrameSem, 1, B_RELATIVE_TIMEOUT, timeout);
123 status_t
124 CamDeframer::GetFrame(CamFrame **frame, bigtime_t *stamp)
126 PRINT((CH "()" CT));
127 BAutolock l(fLocker);
128 CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0);
129 if (!f)
130 return ENOENT;
131 *frame = f;
132 *stamp = f->Stamp();
133 return B_OK;
137 status_t
138 CamDeframer::DropFrame()
140 PRINT((CH "()" CT));
141 BAutolock l(fLocker);
142 CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0);
143 if (!f)
144 return ENOENT;
145 delete f;
146 return B_OK;
150 status_t
151 CamDeframer::RegisterSOFTags(const uint8 **tags, int count, size_t len, size_t skip)
153 if (fSOFTags)
154 return EALREADY;
155 if (len > MAX_TAG_LEN)
156 return EINVAL;
157 if (count > 16)
158 return EINVAL;
159 fSOFTags = tags;
160 fNumSOFTags = count;
161 fLenSOFTags = len;
162 fSkipSOFTags = skip;
163 return B_OK;
167 status_t
168 CamDeframer::RegisterEOFTags(const uint8 **tags, int count, size_t len, size_t skip)
170 if (fEOFTags)
171 return EALREADY;
172 if (len > MAX_TAG_LEN)
173 return EINVAL;
174 if (count > 16)
175 return EINVAL;
176 fEOFTags = tags;
177 fNumEOFTags = count;
178 fLenEOFTags = len;
179 fSkipEOFTags = skip;
180 return B_OK;
185 CamDeframer::FindTags(const uint8 *buf, size_t buflen, const uint8 **tags, int tagcount, size_t taglen, size_t skiplen, int *which)
187 int i, t;
188 for (i = 0; i < (int)(buflen - skiplen + 1); i++) {
189 for (t = 0; t < tagcount; t++) {
190 if (!memcmp(buf+i, tags[t], taglen)) {
191 if (which)
192 *which = t;
193 return i;
197 return -1;
202 CamDeframer::FindSOF(const uint8 *buf, size_t buflen, int *which)
204 return FindTags(buf, buflen, fSOFTags, fNumSOFTags, fLenSOFTags, fSkipSOFTags, which);
209 CamDeframer::FindEOF(const uint8 *buf, size_t buflen, int *which)
211 return FindTags(buf, buflen, fEOFTags, fNumEOFTags, fLenEOFTags, fSkipEOFTags, which);
215 CamFrame *
216 CamDeframer::AllocFrame()
218 return new CamFrame();