MCS  0.3.3-alpha7
Serializable.cc
1 // ----------------------------------------------------------------------^
2 // Copyright (C) 2004, 2005, 2006, 2007, 2008 Giorgio Calderone
3 // (mailto: <gcalderone@ifc.inaf.it>)
4 //
5 // This file is part of MCS.
6 //
7 // MCS is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // MCS is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with MCS; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // ----------------------------------------------------------------------$
22 
23 
24 #include "mcs.hh"
25 using namespace mcs;
26 
27 
28 
29 
30 //--------------------------------------------------------
31 void mcs::Serializable::init(int type, unsigned int lmaxChunksize)
32 {
33  this->type = type;
34  buf = NULL;
35  stream = NULL;
36 
37  lsize = 0;
38  from = NULL;
39  filename = "";
40  freeAfterUse = false;
41 
42  maxChunksize = lmaxChunksize;
43  if (maxChunksize == 0)
44  throw MCS_ERROR(MSG_SIZE_CHUNK, maxChunksize);
45 
46  switch(type) {
47  case MCS_SERIAL_UNKNOWN:
48  case MCS_SERIAL_FILENAME:
49  case MCS_SERIAL_BUFFER:
50  break;
51  default:
52  throw MCS_ERROR(MSG_INVALID_SWITCH, type);
53  }
54 
55  serialize_end();
56 }
57 
58 
59 mcs::Serializable::Serializable(unsigned int lmaxChunksize) {
60  init(MCS_SERIAL_UNKNOWN, lmaxChunksize);
61 }
62 
63 
64 mcs::Serializable::Serializable(void* from, unsigned int size,
65  bool freeAfterUse, unsigned int lmaxChunksize)
66 {
67  init(MCS_SERIAL_BUFFER, lmaxChunksize);
68  this->lsize = size;
69  this->from = (char*) from;
70  this->freeAfterUse = freeAfterUse;
71 }
72 
73 
74 mcs::Serializable::Serializable(string filename, unsigned int lmaxChunksize)
75 {
76  init(MCS_SERIAL_FILENAME, lmaxChunksize);
77  this->filename = filename;
78  File_Dir_Exist(filename, lsize);
79 }
80 
81 
82 mcs::Serializable::Serializable(int type, unsigned int lmaxChunksize)
83 {
84  init(type, lmaxChunksize);
85 }
86 
87 
89  serialize_end();
90 }
91 
92 
93 char* mcs::Serializable::nextChunk_unknown(char* userdata, char* buf,
94  unsigned int& chunksize, bool firstTime)
95 {
96  throw MCS_ERROR(MSG_METHOD_MUST_BE_OVERLOADED, "Serializable::nextChunk_unknown");
97 }
98 
99 char* mcs::Serializable::serialize_unknown()
100 {
101  return NULL;
102 }
103 
104 bool mcs::Serializable::serialize_buffer(char*& from, unsigned int& size)
105 {
106  from = this->from;
107  size = this->lsize;
108  return freeAfterUse;
109 }
110 
111 string mcs::Serializable::serialize_filename()
112 {
113  return filename;
114 }
115 
116 
117 
118 void mcs::Serializable::serialize()
119 {
120  //if (buf) //Maybe from getEntireBuffer
121  // free(buf);
122  //buf = NULL;
123 
124  switch (type) {
125  case MCS_SERIAL_UNKNOWN:
126  userdata = serialize_unknown();
127  buf = (char*) malloc(maxChunksize);
128  break;
129  case MCS_SERIAL_BUFFER:
130  freeAfterUse = serialize_buffer(from, lsize);
131  buf = from;
132  break;
133  case MCS_SERIAL_FILENAME:
134  filename = serialize_filename();
135  if (! File_Dir_Exist(filename, lsize))
136  throw MCS_ERROR(MSG_CANT_OPEN_FILE, filename.csz);
137 
138  stream = new ifstream(filename.c_str(), ios::binary);
139  buf = (char*) malloc(maxChunksize);
140  break;
141  }
142 }
143 
144 
145 void mcs::Serializable::serialize_end()
146 {
147 // LN
148  if (type != MCS_SERIAL_BUFFER) {
149  if (buf)
150  free(buf);
151  }
152  buf = NULL;
153 
154  if (stream)
155  delete stream;
156  stream = NULL;
157 
158  if (type == MCS_SERIAL_BUFFER)
159  if (freeAfterUse)
160  if (from) {
161  free(from);
162  from = NULL;
163  }
164 
165  firstTime = true;
166 }
167 
168 
169 void* mcs::Serializable::nextChunk(unsigned int& chunksize)
170 {
171  unsigned int size_to_send; //To be used only if type == MCS_SERIAL_BUFFER
172 
173  if (firstTime)
174  serialize();
175 
176  switch (type) {
177  case MCS_SERIAL_BUFFER:
178  size_to_send = lsize - (buf - from);
179  chunksize = ( size_to_send < maxChunksize ? size_to_send : maxChunksize );
180 
181  if (! firstTime) {
182  buf += chunksize;
183  size_to_send = lsize - (buf - from);
184  chunksize = ( size_to_send < maxChunksize ? size_to_send : maxChunksize );
185  }
186 
187  if (size_to_send == 0) {
188  buf = NULL; //Here buf is just a cursor, it must not be freed
189  serialize_end();
190  }
191  break;
192 
193  case MCS_SERIAL_FILENAME:
194  if (stream->eof())
195  serialize_end();
196  else {
197  stream->read(buf, maxChunksize);
198  chunksize = stream->gcount();
199  }
200  break;
201 
202  case MCS_SERIAL_UNKNOWN:
203  chunksize = maxChunksize;
204  if (! (userdata = nextChunk_unknown(userdata, buf, chunksize, firstTime)))
205  serialize_end();
206  break;
207  }
208 
209  if (buf) //serialize_end() hasn't been called
210  firstTime = false;
211 
212  return buf;
213 }
214 
215 
216 void* mcs::Serializable::getEntireBuffer(unsigned int& size)
217 {
218  unsigned int chunk;
219  void* tmp;
220  Buffer abuf(DONT_FREE); //*
221 
222  while(( tmp = nextChunk(chunk) ))
223  abuf(chunk) << tmp;
224 
225  size = abuf.size();
226  return abuf[0];
227  //buf = abuf.buffer(); //* = will be freed in the next call to serialize
228  //return buf;
229 }
230 
231 
233 {
234  return (lsize != 0);
235 }
236 
238 {
239  unsigned int nchunk = (unsigned int) (floor((((float) lsize)/maxChunksize)));
240  nchunk++;
241 
242  return nchunk;
243 }
244 
246 {
247  return lsize;
248 }
249 
250 
252 {
253  return maxChunksize;
254 }
255 
256 
Serializable(const Serializable &)
Declared to avoid using of default copy constructor.
virtual char * nextChunk_unknown(char *userdata, char *buf, unsigned int &chunksize, bool firstTime)
Custom routine to fill a buffer with a chunk.
Definition: Serializable.cc:93
bool File_Dir_Exist(string fn, unsigned int &size)
Check if a file or directory exists.
Definition: Utils.cc:39
unsigned int size()
Return size of the buffer.
Definition: Record.cc:208
virtual ~Serializable()
Destructor.
Definition: Serializable.cc:88
#define MCS_ERROR(A, rest...)
Facility to easily pass all necessary parameter to an Event constructor.
Definition: mcs.hh:964
bool knowSize()
Reinitialize internal data.
unsigned int size()
If knowSize() is true, return the size of the entire block of data.
High level buffer.
Definition: mcs.hh:1095
void * nextChunk(unsigned int &chunksize)
Fills a buffer with next chunk to be sent.
Main include file for all MCS based applications.
void init(int type, unsigned int lmaxChunksize)
Common initialization.
Definition: Serializable.cc:31
unsigned int maxChunkSize()
Return the max size allowed for a chunk.
unsigned int nChunk()
If knowSize() is true, return how many chunks are required to send all data.
Namespace for MCS library.

mcslogo

MCS (My Customizable Server) ver. 0.3.3-alpha7
Documentation generated on Mon May 28 07:39:41 UTC 2018