1 /******************************************************************************
2 * Copyright (c) 2014, Hobu Inc.
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following
8 * conditions are met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in
14 *       the documentation and/or other materials provided
15 *       with the distribution.
16 *     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
17 *       names of its contributors may be used to endorse or promote
18 *       products derived from this software without specific prior
19 *       written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 * OF SUCH DAMAGE.
33 ****************************************************************************/
34 
35 #pragma once
36 
37 #include <streambuf>
38 #include <iostream>
39 #include <vector>
40 
41 #include "pdal_util_export.hpp"
42 
43 namespace pdal
44 {
45 
46 /**
47   Allow a data buffer to be used at a std::streambuf.
48 */
49 class Charbuf : public std::streambuf
50 {
51 public:
52     /**
53       Construct an empty Charbuf.
54     */
Charbuf()55     PDAL_DLL Charbuf() : m_bufOffset(0)
56         {}
57 
58     /**
59       Construct a Charbuf that wraps a byte vector.
60 
61       \param v  Byte vector to back streambuf.
62       \param bufOffset  Offset in vector (ignore bytes before offset).
63     */
Charbuf(std::vector<char> & v,pos_type bufOffset=0)64     PDAL_DLL Charbuf (std::vector<char>& v, pos_type bufOffset = 0)
65         { initialize(v.data(), v.size(), bufOffset); }
66 
67     /**
68       Construct a Charbuf that wraps a byte buffer.
69 
70       \param buf  Buffer to back streambuf.
71       \param count  Size of buffer.
72       \param bufOffset  Offset in vector (ignore bytes before offset).
73     */
Charbuf(char * buf,size_t count,pos_type bufOffset=0)74     PDAL_DLL Charbuf (char *buf, size_t count, pos_type bufOffset = 0)
75         { initialize(buf, count, bufOffset); }
76 
77     /**
78       Set a buffer to back a Charbuf.
79 
80       \param buf  Buffer to back streambuf.
81       \param count  Size of buffer.
82       \param bufOffset  Offset in vector (ignore bytes before offset).
83     */
84     PDAL_DLL void initialize(char *buf, size_t count, pos_type bufOffset = 0);
85 
86 protected:
87     /**
88       Seek to a position in the buffer.
89 
90       \param pos  Position to seek to.
91       \param which  I/O mode [default: rw]
92       \return  Current position adjusted for buffer offset.
93     */
94     PDAL_DLL std::ios::pos_type seekpos(std::ios::pos_type pos,
95         std::ios_base::openmode which = std::ios_base::in | std::ios_base::out);
96 
97     /**
98       Seek to a position based on an offset from a position.
99 
100       \param off  Offset from current position.
101       \param dir  Offset basis (beg, cur or end)
102       \param which  I/O mode [default: rw]
103       \return  Current position adjusted for buffer offset.
104     */
105     PDAL_DLL std::ios::pos_type seekoff(std::ios::off_type off,
106         std::ios_base::seekdir dir,
107         std::ios_base::openmode which = std::ios_base::in | std::ios_base::out);
108 
109 private:
110     /**
111       Offset that allows one to seek to positions not based on the beginning
112       of the backing vector, but to some other reference point.
113     */
114     std::ios::pos_type m_bufOffset;
115 
116     /**
117       For the put pointer, it seems we need the beginning of the buffer
118       in order to deal with offsets.
119     */
120     char *m_buf;
121 };
122 
123 } //namespace pdal
124