3 * Copyright (C) 2007, Rus V. Brushkoff, All rights reserved.
7 // - ËÏÎÃÅÐÃÉÑ ÂÕÆÅÒÁ : buf->get/put(sfinx_t)
8 // - rewrite using text or binary XML (ebml) data format
9 // - fix all id's and sizes to 64 bit values
14 #include <arpa/inet.h>
27 typedef unsigned int u32_t;
28 typedef signed int s32_t;
29 typedef unsigned short u16_t;
30 typedef signed short s16_t;
31 typedef unsigned long long u64_t;
32 typedef signed long long s64_t;
33 typedef unsigned char u8_t;
34 typedef signed char s8_t;
36 // ÉÄÅÎÔÉÆÉËÁÔÏÒÙ ÏÂØÅËÔÏ×
37 typedef u32_t sfinx_tid_t;
38 typedef u64_t sfinx_id_t;
39 typedef u64_t sfinx_size_t;
41 typedef u32_t sfinx_type_t;
46 sfinx_t(const sfinx_t &st) { bug(); }
47 sfinx_t &operator=(const sfinx_t &st) { return operator=(&st); }
48 sfinx_t &operator=(const sfinx_t *st) { bug(); return *this; }
50 // ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÐÅÒÅÄÁÞÉ ÏÂØÅËÔÁ ÞÅÒÅÚ ÂÉÎÁÒÎÙÊ ÂÕÆÅÒ
51 // ×ÏÚ×ÒÁÝÁÅÔ ÒÁÚÍÅÒ ÐÏÌÏÖÅÎÎÙÈ × ÂÕÆÅÒ ÄÁÎÎÙÈ
52 virtual sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) = 0;
53 // ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ×ÏÓÓÔÁÎÏ×ÌÅÎÉÑ ÏÂØÅËÔÁ ÉÚ ÂÉÎÁÒÎÏÇÏ ÂÕÆÅÒÁ
54 // ×ÏÚ×ÒÁÝÁÅÔ ÒÁÚÍÅÒ ×ÙÎÕÔÙÈ ÉÚ ÂÕÆÅÒÁ ÄÁÎÎÙÈ
55 virtual sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) = 0;
59 sfinx_size_t size_; // ÒÁÚÍÅÒ ÏÂØÅËÔÁ × ÂÁÊÔÁÈ
60 sfinx_tid_t tid_; // sfinx element type id
61 void copy_size_tid(const sfinx_t *s) { size_ = s->size_; tid_ = s->tid_; }
66 virtual void copy(const sfinx_t *st) = 0;
68 sfinx_t(sfinx_tid_t _tid) { tid_ = _tid; size_ = 0; }
69 virtual ~sfinx_t() { }
71 sfinx_id_t tid() { return tid_; }
72 void tid(sfinx_id_t t) { tid_ = t; }
74 virtual const char *sidstr() { return "generic sfinx object"; }
75 // update size for object
76 virtual sfinx_size_t size() = 0;
77 // try copy object to string
78 virtual bool get(string &s) { debug("class - %s", typeid(*this).name()); bug(); return false; }
79 // try copy object to u32_t
80 virtual bool get(u32_t *v) { debug("class - %s", typeid(*this).name()); bug(); return false; }
81 // try to copy object from string
82 virtual bool set(string &s) { debug("class - %s", typeid(*this).name()); bug(); return false; }
83 // try to copy object from u32_t
84 virtual bool set(u32_t v) { debug("class - %s", typeid(*this).name()); bug(); return false; }
86 friend class sfinx_pair_t;
87 friend class sfinx_elements;
90 static sfinx_t *make_sfinx_element(sfinx_tid_t tid);
92 class sfinx_8bit_t : public sfinx_t {
94 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
95 if (object_size_in_buf) {
101 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
102 if (available_buf_space) {
109 void copy(const sfinx_t *s) {
110 if (!dynamic_cast<const sfinx_8bit_t *>(s))
113 val_ = ((const sfinx_8bit_t *)s)->val_;
115 sfinx_8bit_t() : sfinx_t(SFINX_ELEMENT_8BIT) { }
116 sfinx_8bit_t(sfinx_tid_t _tid) : sfinx_t(_tid) { }
117 sfinx_size_t size() { return (size_ = sizeof(u8_t)); }
118 u8_t get() { return val_; }
119 void set(u8_t v) { val_ = v; size_ = sizeof(u8_t); }
123 class sfinx_8bit_vector_t : public sfinx_t {
125 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
127 for (sfinx_size_t i = 0; i < object_size_in_buf; i++)
128 val.push_back(buf[i]);
131 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
132 if (available_buf_space < size_)
134 for (sfinx_size_t i = 0; i < size_; i++)
139 void copy(const sfinx_t *s) {
140 if (!dynamic_cast<const sfinx_8bit_vector_t *>(s))
144 for (sfinx_size_t i = 0; i < ((const sfinx_8bit_vector_t *)s)->val.size(); i++)
145 val.push_back(((const sfinx_8bit_vector_t *)s)->val[i]);
147 sfinx_8bit_vector_t(sfinx_tid_t _tid = SFINX_ELEMENT_8BIT_VECTOR) : sfinx_t(_tid) { }
148 void clear() { val.clear(); size_ = 0; }
149 void add(u8_t v) { val.push_back(v); size_+= sizeof(u8_t); }
150 bool set(u8_t *b, sfinx_size_t len) { return (get(b, len) != len); }
151 u8_t get(sfinx_size_t idx) { return val[idx]; }
152 sfinx_size_t size() { return (size_ = val.size()); }
153 sfinx_size_t len() { return size(); }
157 class sfinx_32bit_t : public sfinx_t {
159 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
160 if (object_size_in_buf < sizeof(u32_t))
162 val_ = ((u32_t *)buf)[0];
165 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
166 if (available_buf_space < sizeof(u32_t))
168 ((u32_t *)buf)[0] = val_;
172 void copy(const sfinx_t *s) {
173 if (!dynamic_cast<const sfinx_32bit_t *>(s))
176 val_ = ((const sfinx_32bit_t *)s)->val_;
178 sfinx_32bit_t() : sfinx_t(SFINX_ELEMENT_32BIT) { }
179 sfinx_32bit_t(sfinx_tid_t _tid) : sfinx_t(_tid) { }
180 u32_t get() { return val_; }
181 bool get(u32_t *v) { *v = val_; return 0; }
182 bool set(u32_t v) { val_ = v; size(); return 0; }
183 sfinx_size_t size() { return (size_ = sizeof(u32_t)); }
189 using namespace IBPP;
191 class sfinx_timestamp_t : public Timestamp {
193 sfinx_timestamp_t() : Timestamp() { mDate = IBPP::MinDate; mTime = 0; }
194 //sfinx_timestamp_t(const Timestamp &t) : Timestamp(t) { }
195 sfinx_size_t size() { return (sizeof(mDate) + sizeof(mTime)); }
196 sfinx_size_t get(u8_t *buf) {
198 memcpy(&date, buf, sizeof(date));
199 memcpy(&time, buf + sizeof(date), sizeof(time));
204 sfinx_size_t put(u8_t *buf) {
208 memcpy(buf, &date, sizeof(date));
209 memcpy(buf + sizeof(date), &time, sizeof(time));
213 tm *loctime = localtime(&t);
214 if (!IBPP::itod(&mDate, loctime->tm_year + 1900, loctime->tm_mon + 1, loctime->tm_mday))
215 log("sfinx_timestamp_t", "Out of range");
216 IBPP::itot(&mTime, loctime->tm_hour, loctime->tm_min, loctime->tm_sec, 0);
220 // make some libsfinx include
221 // serialize/deserialize methods
222 extern sfinx_size_t get(sfinx_id_t *v, u8_t *buf);
223 extern sfinx_size_t get(sfinx_type_t *v, u8_t *buf);
224 extern sfinx_size_t get(string *v, u8_t *buf);
225 extern sfinx_size_t get(u8_t *v, u8_t *buf);
226 extern sfinx_size_t get(float *v, u8_t *buf);
227 extern sfinx_size_t put(sfinx_id_t &v, u8_t *buf);
228 extern sfinx_size_t put(sfinx_type_t &v, u8_t *buf);
229 extern sfinx_size_t put(string &v, u8_t *buf);
230 extern sfinx_size_t put(u8_t &v, u8_t *buf);
231 extern sfinx_size_t put(float &v, u8_t *buf);
233 class sfinx_object_t {
235 sfinx_id_t id, slice_id;
237 string name, path_name, description;
238 sfinx_timestamp_t ctime, etime;
239 sfinx_object_t() { id = type = 0; }
240 sfinx_object_t(sfinx_type_t t, sfinx_id_t i, sfinx_id_t s) {
245 sfinx_object_t(sfinx_type_t t, sfinx_id_t i, sfinx_id_t s, const char *n, sfinx_timestamp_t &ct,
246 sfinx_timestamp_t &et) {
254 bool cmp(sfinx_object_t *o) {
255 if ((o->id == id) && (o->type == type) && (o->slice_id == o->slice_id))
259 sfinx_size_t size() { return (2 * sizeof(sfinx_id_t) + sizeof(sfinx_type_t) + name.size() + 1 +
260 path_name.size() + 1 + description.size() + 1 + ctime.size() + etime.size()); }
261 sfinx_size_t get(u8_t *buf) {
263 buf += ::get(&id, buf);
264 buf += ::get(&slice_id, buf);
265 buf += ::get(&type, buf);
266 buf += ::get(&name, buf);
267 buf += ::get(&path_name, buf);
268 buf += ::get(&description, buf);
269 buf += ctime.get(buf);
270 buf += etime.get(buf);
273 u32_t put(u8_t *buf) {
275 buf += ::put(id, buf);
276 buf += ::put(slice_id, buf);
277 buf += ::put(type, buf);
278 buf += ::put(name, buf);
279 buf += ::put(path_name, buf);
280 buf += ::put(description, buf);
281 buf += ctime.put(buf);
282 buf += etime.put(buf);
287 extern char tag2char(sfinx_object_t &tag);
288 extern const char *tagtype2str(sfinx_object_t &tag);
290 class sfinx_slice_t : public sfinx_t {
292 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
293 if (available_buf_space < size())
296 buf += ::put(id, buf);
297 buf += ::put(parent_id, buf);
298 buf += ::put(name_, buf);
299 buf += ::put(directory_, buf);
300 buf += ::put(description_, buf);
301 buf += ::put(parent_name_, buf);
302 buf += ctime.put(buf);
303 buf += etime.put(buf);
305 u32_t l = objs.size();
306 buf += ::put(l, buf);
307 for (u32_t i = 0; i < l; i++)
308 buf += objs[i].put(buf);
311 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
313 buf += ::get(&id, buf);
314 buf += ::get(&parent_id, buf);
315 buf += ::get(&name_, buf);
316 buf += ::get(&directory_, buf);
317 buf += ::get(&description_, buf);
318 buf += ::get(&parent_name_, buf);
319 buf += ctime.get(buf);
320 buf += etime.get(buf);
323 buf += ::get(&l, buf);
324 for (u32_t i = 0; i < l; i++) {
329 // hmm, ÐÒÏ×ÅÒËÁ ÌÉÛØ × ËÏÎÃÅ
330 if ((sfinx_size_t)(buf - t) > object_size_in_buf)
337 void copy(const sfinx_t *s) {
338 if (!dynamic_cast<const sfinx_slice_t *>(s))
341 const sfinx_slice_t *s_ = (const sfinx_slice_t *)s;
344 directory_ = s_->directory_;
345 parent_name_ = s_->parent_name_;
346 description_ = s_->description_;
347 parent_id = s_->parent_id;
353 string name_, directory_, description_, parent_name_;
354 sfinx_id_t parent_id;
355 sfinx_timestamp_t ctime, etime;
356 vector <sfinx_object_t> objs; // ×ÌÏÖÅÎÎÙÅ × ÓÌÁÊÓ ÏÂØÅËÔÙ
358 const char *name() { return name_.c_str(); }
359 const char *directory() { return directory_.c_str(); }
360 const char *description() { return description_.c_str(); }
361 const char *parent_name() { return parent_name_.c_str(); }
362 sfinx_object_t *object() {
363 static sfinx_object_t o;
367 o.type = SFINX_SLICE_OBJECT;
368 o.slice_id = o.id = id;
369 o.path_name = directory_;
370 o.description = description_;
374 void add(sfinx_object_t &obj) { objs.push_back(obj); }
375 void name(const char *s) { name_ = s; size(); }
376 void directory(const char *d) { directory_ = d; size(); }
377 void description(const char *s) { description_ = s; size(); }
378 void parent_name(const char *s) { parent_name_ = s; size(); }
380 sfinx_slice_t(sfinx_tid_t tid = SFINX_ELEMENT_SLICE) : sfinx_t(tid) {
384 sfinx_slice_t(sfinx_slice_t *s) : sfinx_t(SFINX_ELEMENT_SLICE) { copy(s); }
385 sfinx_slice_t(sfinx_id_t id_, string &name__, string &directory__, string &description__,
386 string &parent_name__, sfinx_id_t parent_id, sfinx_timestamp_t ctime_, sfinx_timestamp_t etime_,
387 sfinx_tid_t tid = SFINX_ELEMENT_SLICE) : sfinx_t(tid), id(id_), name_(name__),
388 directory_(directory__), description_(description__), parent_name_(parent_name__),
389 parent_id(parent_id), ctime(ctime_), etime(etime_) { size(); }
390 sfinx_size_t size() {
391 u32_t s = sizeof(u32_t); // ÄÌÉÎÁ ÓÞÅÔÞÉËÁ ÏÂØÅËÔÏ×
392 for (u32_t i = 0; i < objs.size(); i++)
394 return (size_ = sizeof(id) + name_.size() + 1 + directory_.size() + 1 +
395 description_.size() + 1 + parent_name_.size() + 1 + sizeof(parent_id) + ctime.size() +
398 friend class sfinx_slice_vector_t;
401 class sfinx_slice_vector_t : public sfinx_t {
403 vector <sfinx_slice_t *> slices;
405 sfinx_size_t size() {
407 for (u32_t i = 0; i < slices.size(); i++)
408 size_ += slices[i]->size();
411 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
413 for (u32_t i = 0; i < slices.size(); i++) {
414 if (slices[i]->put(buf + offset, available_buf_space) != slices[i]->size())
416 available_buf_space -= slices[i]->size();
417 offset += slices[i]->size();
421 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
423 while (object_size_in_buf) {
424 sfinx_slice_t *slice = new sfinx_slice_t;
425 sfinx_size_t res = slice->get(buf + size(), object_size_in_buf);
426 if (res != slice->size()) {
431 if (object_size_in_buf < slice->size())
433 object_size_in_buf -= slice->size();
438 for (u32_t i = 0; i < slices.size(); i++)
444 void copy(const sfinx_t *s) {
445 const sfinx_slice_vector_t *src = dynamic_cast<const sfinx_slice_vector_t *>(s);
450 for (u32_t i = 0; i < src->slices.size(); i++) {
451 sfinx_slice_t *slice = new sfinx_slice_t(src->slices[i]);
452 slices.push_back(slice);
455 sfinx_slice_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_SLICE_VECTOR) : sfinx_t(tid) { }
456 ~sfinx_slice_vector_t() { clear(); }
457 void add(sfinx_slice_t *slice) {
458 sfinx_slice_t *s = new sfinx_slice_t(slice);
459 slices.push_back(s); // ËÏÐÉÒÕÅÍ ÏÂØÅËÔ
460 size_ += slice->size();
462 void add(sfinx_slice_t &slice) { add(&slice); }
463 u32_t len() { return slices.size(); }
464 sfinx_slice_t *get(u32_t idx) { return slices[idx]; }
465 sfinx_slice_t *find(u32_t id) {
466 for (u32_t i = 0; i < slices.size(); i++) {
467 if (id == slices[i]->id)
474 class sfinx_string_t : public sfinx_t {
476 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
477 if (available_buf_space < (s.size() + 1))
482 strcpy((char *)buf, s.c_str());
485 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
490 void copy(const sfinx_t *s_) {
491 if (!dynamic_cast<const sfinx_string_t *>(s_))
494 s = ((const sfinx_string_t *)s_)->s;
496 sfinx_size_t size() { return (size_ = s.size() + 1); }
497 sfinx_string_t(sfinx_tid_t tid = SFINX_ELEMENT_STRING) : sfinx_t(tid) { size_ = 1; }
498 sfinx_string_t(const char *s_) : sfinx_t(SFINX_ELEMENT_STRING) {
502 const char *c_str() { return s.c_str(); }
503 bool get(string &s_) { s_ = s; return true; }
504 bool set(string &s_) {
512 bool set(const char *s_) {
522 // ÐÁÒÁ ÅÌÅÍÅÎÔÏ× int -> sfinx_t
523 class sfinx_pair_t : public sfinx_t {
527 key_ = SFINX_KEY_UNASSIGNED;
533 sfinx_size_t size() { return (size_ = element->size() + 2 * sizeof(u32_t)); } // + element id
534 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
535 if (available_buf_space < size())
537 buf += ::put(key_, buf);
538 sfinx_tid_t eid = element->tid();
539 buf += ::put(eid, buf);
540 //debug("eid - %x, size - %d, space - %d", eid, size(), available_buf_space);
541 if (!element->put(buf, available_buf_space - (sizeof(eid) + sizeof(key_))))
545 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
547 buf += ::get(&key_, buf);
549 buf += ::get(&eid, buf);
550 //debug("eid - %x, size_in_buf - %d", eid, object_size_in_buf);
553 element = make_sfinx_element(eid);
555 element->get(buf, object_size_in_buf - (sizeof(eid) + sizeof(key_)));
561 void copy(const sfinx_t *s) {
562 const sfinx_pair_t *src = dynamic_cast<const sfinx_pair_t *>(s);
567 element = make_sfinx_element(src->element->tid());
570 element->copy(src->element);
573 sfinx_pair_t(sfinx_tid_t tid = SFINX_ELEMENT_PAIR) : sfinx_t(tid) {
574 key_ = SFINX_KEY_UNASSIGNED; element = 0;
576 u32_t key() { return key_; }
577 ~sfinx_pair_t() { clear(); }
578 bool get(u32_t k, uint32_t *v) {
581 return element->get(v);
583 bool get(u32_t k, string &s) {
586 return element->get(s);
588 bool get(u32_t k, sfinx_t **el) {
594 bool set(u32_t k, sfinx_t &e) { return set(k, &e); }
595 bool set(u32_t k, sfinx_t *e) {
596 // ÎÅÐÌÏÈÏ ÂÙ ÐÒÏ×ÅÒÉÔØ ÞÔÏ id() != SFINX_ELEMENT_PAIR
598 element = make_sfinx_element(e->tid()); // ÆÁÂÒÉËÁ ÐÕÓÔÙÈ ÅÌÅÍÅÎÔÏ× ÏÐÒ. ÔÉÐÁ
600 element->copy(e); // ÔÉÐÁ ËÏÎÔÓÒÕËÔÏÒ ËÏÐÉÒÏ×ÁÎÉÑ
607 bool set(u32_t k, string &s) {
609 element = new sfinx_string_t;
612 if (!element->set(s))
619 bool set(u32_t k, const char *s) { string t(s); return set(k, t); }
620 bool set(u32_t k, u32_t v) {
622 element = new sfinx_32bit_t;
628 friend class sfinx_pair_vector_t;
631 // ÎÁÂÏÒ ÐÁÒ ÅÌÅÍÅÎÔÏ× int -> sfinx_t
632 class sfinx_pair_vector_t : public sfinx_t {
633 vector <sfinx_pair_t *> pairs;
634 sfinx_size_t size() {
636 for (u32_t i = 0; i < pairs.size(); i++)
637 size_ += pairs[i]->size();
640 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
641 int32_t space = available_buf_space;
643 for (u32_t i = 0; i < pairs.size(); i++) {
644 u32_t sz = pairs[i]->put(buf + offset, available_buf_space - offset);
645 if (!sz || ((space - sz) < 0))
652 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
653 int32_t space = object_size_in_buf;
657 sfinx_pair_t *pair = new sfinx_pair_t; // id ÔÅÒÑÅÍ
658 int32_t sz = pair->get(buf + offset, object_size_in_buf - offset);
660 if (!sz || (space - sz) < 0)
662 pairs.push_back(pair);
663 size_ += pair->size();
665 //debug("offset - %d, all_size - %d, space - %d", offset, object_size_in_buf, space);
671 for (u32_t i = 0; i < pairs.size(); i++)
676 void copy(const sfinx_t *s) {
677 const sfinx_pair_vector_t *src = dynamic_cast<const sfinx_pair_vector_t *>(s);
682 for (u32_t i = 0; i < src->pairs.size(); i++)
683 if (!add(src->pairs[i]))
686 sfinx_pair_t *find(u32_t k) {
687 for (u32_t i = 0; i < pairs.size(); i++) {
688 if (k == pairs[i]->key())
693 u32_t len() { return pairs.size(); }
694 bool find(u32_t k, u32_t *idx) {
695 for (u32_t i = 0; i < pairs.size(); i++) {
696 if (k == pairs[i]->key()) {
703 sfinx_pair_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_PAIR_VECTOR) : sfinx_t(tid) { }
704 bool add(sfinx_pair_t *p) {
707 sfinx_pair_t *pair = new sfinx_pair_t(p->tid());
709 pairs.push_back(pair);
710 size_ += pair->size();
713 // returns false on error (key exists)
714 bool add(u32_t k, sfinx_t *e) {
717 sfinx_pair_t *p = new sfinx_pair_t;
727 // return false if key not found
728 bool get(u32_t k, uint32_t *v) {
729 sfinx_pair_t *pair = find(k);
732 return pair->get(k, v);
734 bool get(u32_t k, string &s) {
735 sfinx_pair_t *pair = find(k);
738 return pair->get(k, s);
741 // bool get(u32_t k, sfinx_t *s) {
742 // sfinx_pair_t *pair = find(k);
745 // return pair->get(k, s);
748 bool add(u32_t k, uint32_t v) {
751 sfinx_pair_t *pair = new sfinx_pair_t;
756 bool add(u32_t k, string &s) {
759 sfinx_pair_t *pair = new sfinx_pair_t;
764 bool add(u32_t k, const char *s) { string t(s); return add(k, t); }
767 class sfinx_file_t : public sfinx_t {
768 sfinx_size_t size() {
769 u32_t objs_size = sizeof(u32_t); // obj counter
770 for (u32_t i = 0; i < objects.size(); i++)
771 objs_size += objects[i].size();
772 return (size_ = 4 * sizeof(sfinx_id_t) + 2 * sizeof(sfinx_size_t) + objs_size +
773 name.size() + 1 + orig_name.size() + 1 + title.size() + 1 + authority.size() + 1 +
774 description.size() + 1 + comments.size() + 1 + ctime.size() + etime.size() +
775 4 * sizeof(u8_t) + mimetype.size() + 1 + csum.size() + 1 + compressed_csum.size() + 1);
777 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
778 if (size() > available_buf_space)
780 buf += ::put(file_id, buf);
781 u8_t v = is_directory;
782 buf += ::put(v, buf);
784 buf += ::put(v, buf);
785 v = store_compressed;
786 buf += ::put(v, buf);
788 buf += ::put(v, buf);
789 buf += ::put(mtag_id, buf);
790 buf += ::put(mtag_type, buf);
791 buf += ::put(mtag_slice_id, buf);
792 buf += ::put(fsize, buf);
793 buf += ::put(compressed_fsize, buf);
794 u32_t t = objects.size();
795 buf += ::put(t, buf);
796 for (u32_t i = 0; i < objects.size(); i++)
797 buf += objects[i].put(buf);
798 buf += ::put(name, buf);
799 buf += ::put(orig_name, buf);
800 buf += ::put(title, buf);
801 buf += ::put(authority, buf);
802 buf += ::put(description, buf);
803 buf += ::put(comments, buf);
804 buf += ::put(mimetype, buf);
805 buf += ::put(csum, buf);
806 buf += ::put(compressed_csum, buf);
807 buf += ctime.put(buf);
808 buf += etime.put(buf);
811 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
814 buf += ::get(&file_id, buf);
816 buf += ::get(&v, buf);
818 buf += ::get(&v, buf);
820 buf += ::get(&v, buf);
821 store_compressed = v;
822 buf += ::get(&v, buf);
824 buf += ::get(&mtag_id, buf);
825 buf += ::get(&mtag_type, buf);
826 buf += ::get(&mtag_slice_id, buf);
827 buf += ::get(&fsize, buf);
828 buf += ::get(&compressed_fsize, buf);
830 buf += ::get(&objects_size, buf);
831 for (u32_t i = 0; i < objects_size; i++) {
834 objects.push_back(o);
836 buf += ::get(&name, buf);
837 buf += ::get(&orig_name, buf);
838 buf += ::get(&title, buf);
839 buf += ::get(&authority, buf);
840 buf += ::get(&description, buf);
841 buf += ::get(&comments, buf);
842 buf += ::get(&mimetype, buf);
843 buf += ::get(&csum, buf);
844 buf += ::get(&compressed_csum, buf);
845 buf += ctime.get(buf);
846 buf += etime.get(buf);
847 if (size() != (sfinx_size_t)(buf - tmp))
854 file_id = mtag_type = mtag_id = fsize = 0;
855 is_directory = false;
857 } void copy(const sfinx_t *s) {
858 const sfinx_file_t *src = dynamic_cast<const sfinx_file_t *>(s);
862 ((sfinx_t *)s)->size();
864 file_id = src->file_id;
865 mtag_id = src->mtag_id;
866 mtag_type = src->mtag_type;
867 mtag_slice_id = src->mtag_slice_id;
869 compressed_fsize = src->compressed_fsize;
871 orig_name = src->orig_name;
873 authority = src->authority;
874 description = src->description;
875 comments = src->comments;
878 objects = src->objects;
879 is_directory = src->is_directory;
880 sorted_location = src->sorted_location;
881 store_compressed = src->store_compressed;
882 generate_csum = src->generate_csum;
883 mimetype = src->mimetype;
885 compressed_csum = src->compressed_csum;
887 sfinx_id_t file_id, mtag_id, mtag_type, mtag_slice_id;
888 sfinx_size_t fsize, compressed_fsize;
889 string name, orig_name, title, authority, description, comments, mimetype, csum,
891 sfinx_timestamp_t ctime, etime;
892 bool is_directory, sorted_location, store_compressed, generate_csum;
893 vector <sfinx_object_t> objects; // ÍÁÓÓÉ× ÔÉÐÏ× É id ÄÏÐÏÌÎÉÔÅÌØÎÙÈ ÏÂØÅËÔÏ×
894 sfinx_file_t(sfinx_tid_t tid = SFINX_ELEMENT_FILE) : sfinx_t(tid) { clear(); }
895 const char *sidstr() { return "File"; }
897 friend class sfinx_files_vector_t;
900 class sfinx_files_vector_t : public sfinx_t {
902 for (u32_t i = 0; i < files.size(); i++)
907 sfinx_size_t size() {
909 for (u32_t i = 0; i < files.size(); i++)
910 size_ += files[i]->size();
913 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
914 int32_t space = available_buf_space;
916 for (u32_t i = 0; i < files.size(); i++) {
917 int32_t sz = files[i]->put(buf + offset, available_buf_space - offset);
918 if (!sz || ((space - sz) < 0))
925 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
926 int32_t space = object_size_in_buf;
930 sfinx_file_t *file = new sfinx_file_t;
931 int32_t sz = file->get(buf + offset, object_size_in_buf - offset);
935 if ((space - sz) < 0)
937 files.push_back(file);
938 size_ += file->size();
944 void copy(const sfinx_t *s) {
945 const sfinx_files_vector_t *src = dynamic_cast<const sfinx_files_vector_t *>(s);
950 for (u32_t i = 0; i < src->files.size(); i++)
951 if (!add(src->files[i]))
954 vector <sfinx_file_t *> files;
955 sfinx_files_vector_t(sfinx_tid_t tid = SFINX_ELEMENT_FILE_VECTOR) : sfinx_t(tid) { clear(); }
956 ~sfinx_files_vector_t() { clear(); }
957 bool add(sfinx_file_t &f) { return add(&f); }
958 bool add(sfinx_file_t *f) {
959 sfinx_file_t *nf = new sfinx_file_t;
968 class sfinx_note_t : public sfinx_t {
969 sfinx_size_t size() {
971 u32_t tags_size = sizeof(u32_t);
972 for (u32_t i = 0; i < tags.size(); i++)
973 tags_size += tags[i].size();
974 return (size_ = tags_size + sizeof(sfinx_id_t) + mtag.size() + name.size() + 1 +
975 url.size() + 1 + text.size() + 1 + sizeof(u8_t) + ctime.size() + etime.size());
977 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
978 if (size() > available_buf_space)
980 buf += ::put(id, buf);
981 buf += mtag.put(buf);
982 buf += ::put(name, buf);
983 buf += ::put(url, buf);
984 buf += ::put(text, buf);
985 buf += ::put(secured, buf);
986 buf += ctime.put(buf);
987 buf += etime.put(buf);
988 u32_t x = tags.size();
989 buf += ::put(x, buf);
990 for (u32_t i = 0; i < x; i++)
991 buf += tags[i].put(buf);
994 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
996 buf += ::get(&id, buf);
997 buf += mtag.get(buf);
998 buf += ::get(&name, buf);
999 buf += ::get(&url, buf);
1000 buf += ::get(&text, buf);
1001 buf += ::get(&secured, buf);
1002 buf += ctime.get(buf);
1003 buf += etime.get(buf);
1005 buf += ::get(&x, buf);
1006 for (u32_t i = 0; i < x; i++) {
1011 if (size() != (sfinx_size_t)(buf - tmp))
1016 void copy(const sfinx_t *s) {
1017 const sfinx_note_t *src = dynamic_cast<const sfinx_note_t *>(s);
1020 ((sfinx_t *)s)->size();
1027 secured = src->secured;
1033 string name, url, text;
1034 u8_t secured; // 0 - none, 1 - crypted text, 2 - crypted text + url, 3 - all crypted
1035 sfinx_timestamp_t ctime, etime;
1036 sfinx_object_t mtag; // main tag
1037 vector <sfinx_object_t> tags;
1038 sfinx_note_t(sfinx_tid_t tid = SFINX_ELEMENT_NOTE) : sfinx_t(tid) { size(); secured = 0; }
1043 class sfinx_progress_t : public sfinx_t {
1045 string label_, strval_;
1046 u8_t status_, type_, precision_;
1047 float max_, val_, old_val;
1048 sfinx_size_t size() {
1049 return (size_ = 3 * sizeof(u8_t) + label_.size() + 1 + 2 * sizeof(float));
1051 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
1053 buf += ::get(&label_, buf);
1054 buf += ::get(&status_, buf);
1055 buf += ::get(&type_, buf);
1056 buf += ::get(&precision_, buf);
1057 buf += ::get(&max_, buf);
1058 buf += ::get(&val_, buf);
1059 if (size() != (sfinx_size_t)(buf - tmp))
1063 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
1064 if (size() > available_buf_space)
1066 buf += ::put(label_, buf);
1067 buf += ::put(status_, buf);
1068 buf += ::put(type_, buf);
1069 buf += ::put(precision_, buf);
1070 buf += ::put(max_, buf);
1071 buf += ::put(val_, buf);
1075 void copy(const sfinx_t *s) {
1076 const sfinx_progress_t *src = dynamic_cast<const sfinx_progress_t *>(s);
1080 label_ = src->label_;
1081 status_ = src->status_;
1085 precision_ = src->precision_;
1087 sfinx_progress_t(sfinx_tid_t tid = SFINX_ELEMENT_PROGRESS) : sfinx_t(tid) {
1088 val_ = max_ = old_val = 0;
1089 type_ = SFINX_PROGRESS_PERCENT;
1091 status_ = SFINX_PROGRESS_NONE;
1094 void precision(char p) { precision_ = p; }
1095 void type(char t) { type_ = t; }
1096 sfinx_progress_t(const char *l) : sfinx_t(SFINX_ELEMENT_PROGRESS) {
1098 val_ = max_ = old_val = 0;
1099 type_ = SFINX_PROGRESS_PERCENT;
1101 status_ = SFINX_PROGRESS_START;
1104 void max(float m) { max_ = m; status_ = SFINX_PROGRESS_START; }
1105 float max() { return max_; }
1106 float value() { return val_; }
1107 const char *strvalue() {
1110 case SFINX_PROGRESS_PERCENT:
1111 sprintf(buf, "%.*f %%", (int) precision_, (val_/max_) * 100.0);
1113 case SFINX_PROGRESS_INTEGER:
1114 sprintf(buf, "%d", (int) val_);
1116 case SFINX_PROGRESS_FLOAT:
1117 sprintf(buf, "%.*f", (int) precision_, val_);
1121 return strval_.c_str();
1123 void end() { status_ = SFINX_PROGRESS_END; };
1124 int status() { return status_; }
1125 const char *label() { return label_.c_str(); }
1126 // p - percent offset - ÅÓÌÉ ÚÎÁÞÅÎÉÅ ÉÚÍÅÎÉÌÏÓØ ÂÏÌÅÅ ÞÅÍ ÎÁ p - return true
1127 bool set(float v, float p) {
1129 if (fabsf((v - old_val)/100.0) >= p) {
1140 class sfinx_search_query_t : public sfinx_t {
1142 vector <u32_t> areas;
1145 sfinx_size_t size() { return (size_ = pattern.size() + 1); }
1146 sfinx_size_t put(u8_t *buf, sfinx_size_t available_buf_space) {
1147 if (size() > available_buf_space)
1149 buf += ::put(pattern, buf);
1152 sfinx_size_t get(u8_t *buf, sfinx_size_t object_size_in_buf) {
1153 buf += ::get(&pattern, buf);
1157 void copy(const sfinx_t *s) {
1158 const sfinx_search_query_t *q = dynamic_cast<const sfinx_search_query_t *>(s);
1162 pattern = q->pattern;
1166 sfinx_search_query_t(sfinx_tid_t tid = SFINX_ELEMENT_SEARCH_QUERY) : sfinx_t(tid) { size(); }
1167 void add_area(u32_t area) { areas.push_back(area); }
1170 static sfinx_t *make_sfinx_element(sfinx_tid_t tid)
1173 case SFINX_ELEMENT_8BIT:
1174 case SFINX_ACCESS_GRANTED:
1175 case SFINX_ACCESS_DENIED:
1176 // case SFINX_SLICES_MODULE_TREE_REQUEST:
1177 case SFINX_FILES_MODULE_CONF_REQUEST:
1178 return new sfinx_8bit_t(tid);
1179 case SFINX_ELEMENT_32BIT:
1180 case SFINX_DELETE_SLICE_WITH_REATTACH:
1181 case SFINX_DELETE_SLICE_ASSOC_DATA:
1182 case SFINX_DELETE_SLICE_ASSOC_DATA_RECURSIVLY:
1183 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED:
1184 case SFINX_DELETE_SLICE_MARK_DATA_UNSORTED_RECURSIVLY:
1185 case SFINX_DELETE_SLICE_RECURSIVLY:
1186 case SFINX_EDIT_SLICE_REQUEST:
1187 // case SFINX_SLICES_MODULE_TREE_REQUEST_EXCEPT:
1188 case SFINX_OBJECTS_TREE_REQUEST:
1189 return new sfinx_32bit_t(tid);
1190 case SFINX_ELEMENT_8BIT_VECTOR:
1191 case SFINX_DAEMON_VERSION:
1192 case SFINX_PACKET_CRYPT_TYPES:
1193 case SFINX_MIN_AUTH_LEVELS:
1195 case SFINX_AUTH_REQUEST:
1196 return new sfinx_8bit_vector_t(tid);
1197 case SFINX_ELEMENT_SLICE:
1198 case SFINX_EDIT_SLICE:
1199 case SFINX_NEW_SLICE:
1200 case SFINX_SLICE_RELINK:
1201 // case SFINX_NOTES_MODULE_TREE_REQUEST:
1202 return new sfinx_slice_t(tid);
1203 case SFINX_ELEMENT_SLICE_VECTOR:
1204 // case SFINX_SLICES_MODULE_TREE:
1205 // case SFINX_SLICES_MODULE_TREE_EXCEPT:
1206 // case SFINX_NOTES_MODULE_TREE:
1207 case SFINX_OBJECTS_TREE:
1208 return new sfinx_slice_vector_t(tid);
1209 case SFINX_ELEMENT_PAIR:
1210 return new sfinx_pair_t(tid);
1211 case SFINX_ELEMENT_PAIR_VECTOR:
1212 case SFINX_FILES_MODULE_CONF:
1213 return new sfinx_pair_vector_t(tid);
1214 case SFINX_ELEMENT_STRING:
1216 case SFINX_FILES_MODULE_CLASSIFY_REPLY:
1217 case SFINX_FILES_MODULE_EDIT_REPLY:
1218 case SFINX_NOTES_MODULE_ADD_REPLY:
1219 case SFINX_NOTES_MODULE_EDIT_REPLY:
1220 case SFINX_FILES_MODULE_UNLINK:
1221 return new sfinx_string_t(tid);
1222 case SFINX_ELEMENT_FILE_VECTOR:
1223 // case SFINX_FILES_MODULE_SORTED_TREE:
1224 case SFINX_FILES_MODULE_UNSORTED_TREE:
1225 return new sfinx_files_vector_t(tid);
1226 case SFINX_ELEMENT_PROGRESS:
1227 return new sfinx_progress_t(tid);
1228 case SFINX_ELEMENT_FILE:
1229 case SFINX_FILES_MODULE_CLASSIFY_REQUEST:
1230 // case SFINX_FILES_MODULE_SORTED_TREE_REQUEST:
1231 case SFINX_FILES_MODULE_UNSORTED_TREE_REQUEST:
1232 case SFINX_FILES_MODULE_EDIT_REQUEST:
1233 case SFINX_FILES_MODULE_EDIT_FILE:
1234 case SFINX_FILES_MODULE_SORTED_UNLINK:
1235 case SFINX_FILES_MODULE_UNSORT:
1236 return new sfinx_file_t(tid);
1237 case SFINX_ELEMENT_SEARCH_QUERY:
1238 return new sfinx_search_query_t(tid);
1239 case SFINX_ELEMENT_SEARCH_RESULT:
1240 return new sfinx_pair_vector_t(tid);
1241 case SFINX_NOTES_MODULE_ADD:
1242 case SFINX_NOTES_MODULE_EDIT_REQUEST:
1243 case SFINX_NOTES_MODULE_EDIT:
1244 case SFINX_NOTES_MODULE_UNLINK:
1245 case SFINX_NOTES_MODULE_UNSORT:
1246 return new sfinx_note_t(tid);
1248 debug("Unknown element %s (id 0x%x)", sfinx_cmd2str(tid), tid);
1253 //sfinx_32bit_vector_t
1255 //sfinx_64bit_vector_t
1257 //sfinx_float_vector_t
1259 //sfinx_double_vector_t
1260 //sfinx_string_vector_t
1262 //sfinx_date_vector_t
1265 // TODO: - support for 64 bit lengths/values
1267 // ÎÅËÉÊ ÂÕÆÅÒ ÉÚ sfinx ÜÌÅÍÅÎÔÏ×
1268 class sfinx_elements {
1270 sfinx_size_t data_offset_, allocated_size_;
1272 u32_t n_elements, current_element;
1274 vector <sfinx_t *> elements;
1275 // u32_t curr_offset;
1278 u32_t count(sfinx_tid_t tid) {
1280 for (u32_t i = 0; i < elements.size(); i++) {
1281 if (elements[i]->tid() == tid)
1287 if (current_element == elements.size())
1290 return elements[current_element++];
1292 sfinx_t *get(sfinx_tid_t el_id, u32_t el_offset = 0) {
1293 for (u32_t i = 0; i < elements.size(); i++) {
1295 if (elements[i]->tid() == el_id) {
1304 // parse elements from binary buffer
1305 bool parse(u8_t *buf, u32_t buf_len) {
1306 u32_t current_position = 0;
1307 current_element = 0;
1308 s32_t buf_len_ = buf_len;
1312 u8_t first_byte = buf[current_position]; // id byte
1313 u8_t id_len = decoded_size(first_byte);
1314 memcpy(((u8_t *)&id_be32) + (sizeof(u32_t) - id_len), buf + current_position, id_len);
1315 sfinx_tid_t id = decode(id_be32, id_len);
1316 current_position += id_len;
1319 first_byte = buf[current_position]; // len byte
1320 u8_t len_size = decoded_size(first_byte);
1321 memcpy(((u8_t *)&len_be32) + (sizeof(u32_t) - len_size), buf + current_position, len_size);
1322 u32_t len = decode(len_be32, len_size);
1323 current_position += len_size;
1324 buf_len_ -= (id_len + len_size + len);
1325 debug("got object %s, id_len - %d, len_size - %d, object len - %d, buf_len - %d",
1326 sfinx_cmd2str(id), id_len, len_size, len, buf_len);
1328 debug("Obj %s has zero len", sfinx_cmd2str(id));
1330 debug("Too small buf len");
1335 el = make_sfinx_element(id);
1339 sfinx_size_t copied = el->get(buf + current_position, len);
1340 if (copied != len) {
1341 debug("%s parsing error, copied %lld from %d !", sfinx_cmd2str(id), copied, len);
1346 elements.push_back(el);
1347 debug("parsed ok: object: %s, len - %d", sfinx_cmd2str(id), len);
1348 } // else buf_len is ok
1350 current_position += len;
1354 sfinx_elements() { buf_ = 0; clear(); }
1355 ~sfinx_elements() { clear(); }
1356 static s8_t decoded_size(u8_t first_byte) {
1358 for (s8_t size = 0; size < 4; size++) {
1359 if (first_byte & (mask >> size))
1364 static s8_t coded_size(u32_t val) {
1365 if (val < 0x7F) // 2^7 - 1
1367 else if (val < 0x3FFFL) // 2^14 - 1
1369 else if (val < 0x1FFFFFL) // 2^21 - 1
1371 else if (val < 0x0FFFFFFFL) // 2^28 - 1
1376 // code value in utf8-like manner
1377 // returns be32 value
1378 static u32_t code(u32_t val, s8_t *coded_size_ = 0) {
1379 s8_t _coded_size_ = coded_size(val);
1380 if (_coded_size_ < 1)
1382 u8_t msb = (val >> ((_coded_size_ - 1) * 8)) & 0xFF;
1384 msb &= (0xFF >> (_coded_size_ - 1));
1385 msb |= (0x80 >> (_coded_size_ - 1));
1386 val &= ~(0xFFL << ((_coded_size_ - 1) * 8));
1387 val |= (msb << ((_coded_size_ - 1) * 8));
1389 *coded_size_ = _coded_size_;
1392 static u32_t decode(u32_t val_be32, s8_t decode_size) {
1393 val_be32 &= ~((0x80000000L >> (8 * (decode_size - 1))) >> (decode_size - 1));
1394 return ntohl(val_be32);
1397 data_offset_ = allocated_size_ = 0;
1402 for (u32_t i = 0; i < elements.size(); i++)
1405 current_element = 0;
1407 int add(sfinx_t &el) { return add(&el); }
1408 int add(sfinx_t *element) {
1409 s8_t element_id_size = -1, element_length_size = -1;
1410 u32_t coded_id_be32 = code(element->tid(), &element_id_size),
1411 coded_element_length_be32 = code(element->size(), &element_length_size);
1412 if ((element_id_size < 0) || (element_length_size < 0))
1414 sfinx_size_t space = element->size() + data_offset_ + element_id_size + element_length_size;
1415 if (space > allocated_size_) {
1417 u8_t *buf = new u8_t[space];
1418 if (allocated_size_) {
1419 memcpy(buf, buf_, allocated_size_);
1422 allocated_size_ = space;
1426 memcpy(buf_ + data_offset_, ((u8_t *)&coded_id_be32) + (sizeof(u32_t) - element_id_size),
1428 data_offset_ += element_id_size;
1429 // add element length
1430 memcpy(buf_ + data_offset_, ((u8_t *)&coded_element_length_be32) + (sizeof(u32_t) -
1431 element_length_size), element_length_size);
1432 data_offset_ += element_length_size;
1434 sfinx_size_t res = element->put(buf_ + data_offset_, allocated_size_ - data_offset_);
1435 if (res != element->size()) {
1436 debug("%s data copy error: buf_size - %lld, el_size - %lld, copied - %lld",
1437 sfinx_cmd2str(element->tid()), allocated_size_ - data_offset_, element->size(), res);
1440 data_offset_ += element->size();
1441 debug("sending %s, el_id_size - %d, el_len - %lld (be_len 0x%x), el_len_size - %d, "
1442 "copied - %lld, data_size in tx_buf - %lld", sfinx_cmd2str(element->tid()),
1443 element_id_size, element->size(), coded_element_length_be32, element_length_size,
1448 sfinx_size_t size() { return data_offset_; }
1449 u8_t *buf() { return buf_; }