source: vendor/synergy/current/lib/io/CStreamBuffer.cpp

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 2.9 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2002 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include "CStreamBuffer.h"
16
17//
18// CStreamBuffer
19//
20
21const UInt32 CStreamBuffer::kChunkSize = 4096;
22
23CStreamBuffer::CStreamBuffer() :
24 m_size(0),
25 m_headUsed(0)
26{
27 // do nothing
28}
29
30CStreamBuffer::~CStreamBuffer()
31{
32 // do nothing
33}
34
35const void*
36CStreamBuffer::peek(UInt32 n)
37{
38 assert(n <= m_size);
39
40 // reserve space in first chunk
41 ChunkList::iterator head = m_chunks.begin();
42 head->reserve(n + m_headUsed);
43
44 // consolidate chunks into the first chunk until it has n bytes
45 ChunkList::iterator scan = head;
46 ++scan;
47 while (head->size() - m_headUsed < n && scan != m_chunks.end()) {
48 head->insert(head->end(), scan->begin(), scan->end());
49 scan = m_chunks.erase(scan);
50 }
51
52 return reinterpret_cast<const void*>(&(head->begin()[m_headUsed]));
53}
54
55void
56CStreamBuffer::pop(UInt32 n)
57{
58 // discard all chunks if n is greater than or equal to m_size
59 if (n >= m_size) {
60 m_size = 0;
61 m_headUsed = 0;
62 m_chunks.clear();
63 return;
64 }
65
66 // update size
67 m_size -= n;
68
69 // discard chunks until more than n bytes would've been discarded
70 ChunkList::iterator scan = m_chunks.begin();
71 assert(scan != m_chunks.end());
72 while (scan->size() - m_headUsed <= n) {
73 n -= scan->size() - m_headUsed;
74 m_headUsed = 0;
75 scan = m_chunks.erase(scan);
76 assert(scan != m_chunks.end());
77 }
78
79 // remove left over bytes from the head chunk
80 if (n > 0) {
81 m_headUsed += n;
82 }
83}
84
85void
86CStreamBuffer::write(const void* vdata, UInt32 n)
87{
88 assert(vdata != NULL);
89
90 // ignore if no data, otherwise update size
91 if (n == 0) {
92 return;
93 }
94 m_size += n;
95
96 // cast data to bytes
97 const UInt8* data = reinterpret_cast<const UInt8*>(vdata);
98
99 // point to last chunk if it has space, otherwise append an empty chunk
100 ChunkList::iterator scan = m_chunks.end();
101 if (scan != m_chunks.begin()) {
102 --scan;
103 if (scan->size() >= kChunkSize) {
104 ++scan;
105 }
106 }
107 if (scan == m_chunks.end()) {
108 scan = m_chunks.insert(scan, Chunk());
109 }
110
111 // append data in chunks
112 while (n > 0) {
113 // choose number of bytes for next chunk
114 assert(scan->size() <= kChunkSize);
115 UInt32 count = kChunkSize - scan->size();
116 if (count > n)
117 count = n;
118
119 // transfer data
120 scan->insert(scan->end(), data, data + count);
121 n -= count;
122 data += count;
123
124 // append another empty chunk if we're not done yet
125 if (n > 0) {
126 ++scan;
127 scan = m_chunks.insert(scan, Chunk());
128 }
129 }
130}
131
132UInt32
133CStreamBuffer::getSize() const
134{
135 return m_size;
136}
Note: See TracBrowser for help on using the repository browser.