1+ #include " AudioTools/CoreAudio/BaseStream.h"
2+ namespace audio_tools {
3+ /* *
4+ * @brief A Arduino Stream which makes sure that we read back the same size
5+ * as we wrote. It adds a size prefix to the data stream.
6+ * @author Phil Schatzmann
7+ */
8+ class ObjectStream : public BaseStream {
9+ ObjectStream (Stream &stream) {
10+ p_in = &stream;
11+ p_out = &stream;
12+ }
13+ ObjectStream (Print &stream) { p_out = &stream; }
14+
15+ // / reads the data from the input stream: I recommend to set the len to the
16+ // / max object size, to avoid that we read only a part of the object.
17+ size_t readBytes (uint8_t *data, size_t len) {
18+ if (p_in == nullptr ) return 0 ;
19+ // read the size prefix if necessary
20+ int to_read = available ();
21+ size_t result = 0 ;
22+ if (to_read > 0 ) {
23+ if (to_read > len) to_read = len;
24+ // read the data
25+ result = p_in->readBytes (data, to_read);
26+ // determe the open number of bytes
27+ n_open_read -= result;
28+ is_complete = n_open_read == 0 ;
29+ // if we have read all data we need to read the size prefix again
30+ if (is_complete) n_open_read = -1 ;
31+ }
32+ return result;
33+ }
34+
35+ size_t write (const uint8_t *data, size_t len) {
36+ if (p_out == nullptr ) return 0 ;
37+ // write the size prefix
38+ p_out->write ((uint8_t *)&len, sizeof (size_t ));
39+ // write the data
40+ return p_out->write (data, len);
41+ }
42+
43+ int available () {
44+ if (p_in == nullptr ) return 0 ;
45+ if (n_open_read >= 0 ) return n_open_read;
46+ // make sure that we can read the size prefix
47+ if (p_in->available () < sizeof (size_t )) return 0 ;
48+ // read the size prefix
49+ p_in->readBytes ((uint8_t *)&n_open_read, sizeof (size_t ));
50+ return n_open_read;
51+ }
52+
53+ // not supported
54+ virtual size_t write (uint8_t ch) { return 0 ; }
55+
56+ int availableForWrite () override {
57+ if (max_object_size > 0 ) return max_object_size;
58+ if (p_out == nullptr ) return DEFAULT_BUFFER_SIZE;
59+ return p_out->availableForWrite ();
60+ }
61+
62+ // / When value is 0 (default) we determine it from the output, otherwise we
63+ // / return the defined value.
64+ void setMaxObjectSize (size_t size) { max_object_size = size; }
65+
66+ // / Determine if we processed the complete object
67+ bool isObjectComplete () { return is_complete; }
68+
69+ protected:
70+ Stream *p_in = nullptr ;
71+ Print *p_out = nullptr ;
72+ int n_open_read = -1 ;
73+ int max_object_size = 0 ; // 0 u
74+ bool is_complete = true ;
75+ };
76+ } // namespace audio_tools
0 commit comments