NCBI C++ ToolKit
objistrjson.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: objistrjson.cpp 75692 2016-12-07 14:14:50Z gouriano $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Andrei Gourianov
27 *
28 * File Description:
29 * JSON object input stream
30 *
31 */
32 
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbistd.hpp>
35 #include <corelib/ncbi_limits.h>
36 
37 #include <serial/objistrjson.hpp>
38 
39 #define NCBI_USE_ERRCODE_X Serial_OStream
40 
42 
44 {
45  return new CObjectIStreamJson();
46 }
47 
48 
51  m_FileHeader(false),
52  m_BlockStart(false),
53  m_ExpectValue(false),
54  m_GotNameless(false),
55  m_Closing(0),
56  m_StringEncoding( eEncoding_UTF8 ),
57  m_BinaryFormat(eDefault)
58 {
59  m_Utf8Pos = m_Utf8Buf.begin();
60 }
61 
64  m_FileHeader(false),
65  m_BlockStart(false),
66  m_ExpectValue(false),
67  m_GotNameless(false),
68  m_Closing(0),
69  m_StringEncoding( eEncoding_UTF8 ),
70  m_BinaryFormat(eDefault)
71 {
72  m_Utf8Pos = m_Utf8Buf.begin();
73  Open(in, deleteIn);
74 }
75 
77 {
78 }
79 
81 {
83  if (GetStackDepth() > 1) {
84  return;
85  }
86  m_LastTag.clear();
87  m_RejectedTag.clear();
88  m_Utf8Buf.clear();
89  m_Utf8Pos = m_Utf8Buf.begin();
90 }
91 
93 {
94  return "line "+NStr::SizetToString(m_Input.GetLine());
95 }
96 
98 {
99  m_StringEncoding = enc;
100 }
101 
103 {
104  return m_StringEncoding;
105 }
106 
109 {
110  return m_BinaryFormat;
111 }
113 {
114  m_BinaryFormat = fmt;
115 }
116 
118 {
119  return m_Input.GetChar();
120 }
121 
123 {
124  return m_Input.PeekChar();
125 }
126 
127 char CObjectIStreamJson::GetChar(bool skipWhiteSpace)
128 {
129  return skipWhiteSpace? SkipWhiteSpaceAndGetChar(): m_Input.GetChar();
130 }
131 
132 char CObjectIStreamJson::PeekChar(bool skipWhiteSpace)
133 {
134  return skipWhiteSpace? SkipWhiteSpace(): m_Input.PeekChar();
135 }
136 
138 {
140 }
141 
143 {
144  try { // catch CEofException
145  for ( ;; ) {
146  char c = m_Input.SkipSpaces();
147  switch ( c ) {
148  case '\t':
149  m_Input.SkipChar();
150  continue;
151  case '\r':
152  case '\n':
153  m_Input.SkipChar();
154  SkipEndOfLine(c);
155  continue;
156  default:
157  return c;
158  }
159  }
160  } catch (CEofException& e) {
161  ThrowError(fEOF, e.what());
162  }
163  return '\0';
164 }
165 
167 {
168  char c = SkipWhiteSpace();
169  m_Input.SkipChar();
170  return c;
171 }
172 
173 bool CObjectIStreamJson::GetChar(char expect, bool skipWhiteSpace /* = false*/)
174 {
175  if ( PeekChar(skipWhiteSpace) != expect ) {
176  return false;
177  }
178  m_Input.SkipChar();
179  return true;
180 }
181 
182 void CObjectIStreamJson::Expect(char expect, bool skipWhiteSpace /* = false*/)
183 {
184  if ( !GetChar(expect, skipWhiteSpace) ) {
185  string msg("\'");
186  msg += expect;
187  msg += "' expected";
188  ThrowError(fFormatError, msg);
189  }
190 }
191 
193  const CItemsInfo& items)
194 {
195  string message =
196  "\""+string(id)+"\": unexpected member, should be one of: ";
197  for ( CItemsInfo::CIterator i(items); i.Valid(); ++i ) {
198  message += '\"' + items.GetItemInfo(i)->GetId().ToString() + "\" ";
199  }
200  ThrowError(fFormatError, message);
201 }
202 
203 
204 int CObjectIStreamJson::ReadEscapedChar(bool* encoded /*=0*/)
205 {
206  char c = GetChar();
207  if (c == '\\') {
208  if (encoded) {
209  *encoded = true;
210  }
211  c = GetChar();
212  if (c == 'u') {
213  int v = 0;
214  for (int p=0; p<4; ++p) {
215  c = GetChar();
216  if (c >= '0' && c <= '9') {
217  v = v * 16 + (c - '0');
218  } else if (c >= 'A' && c <= 'F') {
219  v = v * 16 + (c - 'A' + 0xA);
220  } else if (c >= 'a' && c <= 'f') {
221  v = v * 16 + (c - 'a' + 0xA);
222  } else {
224  "invalid symbol in escape sequence");
225  }
226  }
227  return v;
228  }
229  } else {
230  if (encoded) {
231  *encoded = false;
232  }
233  }
234  return c & 0xFF;
235 }
236 
238 {
240  EEncoding enc_in(eEncoding_UTF8);
241 
242  if (enc_out == eEncoding_UTF8 &&
243  !m_Utf8Buf.empty() && m_Utf8Pos != m_Utf8Buf.end()) {
244  if (++m_Utf8Pos != m_Utf8Buf.end()) {
245  return *m_Utf8Pos & 0xFF;
246  } else {
247  m_Utf8Buf.clear();
248  }
249  }
250  int c = ReadEscapedChar(&encoded);
251  if (enc_out != eEncoding_Unknown) {
252  if (encoded) {
253  TUnicodeSymbol chU = c;
254  if (enc_out == eEncoding_UTF8) {
255  m_Utf8Buf = CUtf8::AsUTF8( &chU, 1);
256  m_Utf8Pos = m_Utf8Buf.begin();
257  return *m_Utf8Pos & 0xFF;
258  } else {
259  return CUtf8::SymbolToChar( chU, enc_out);
260  }
261  }
262  if (enc_in != enc_out) {
263  if (enc_out != eEncoding_UTF8) {
264  TUnicodeSymbol chU = enc_in == eEncoding_UTF8 ?
265  ReadUtf8Char((char)c) : CUtf8::CharToSymbol((char)c, enc_in);
266  Uint1 ch = CUtf8::SymbolToChar( chU, enc_out);
267  return ch & 0xFF;
268  }
269  if ((c & 0x80) == 0) {
270  return c;
271  }
272  char ch = (char)c;
273  m_Utf8Buf = CUtf8::AsUTF8( CTempString(&ch,1), enc_in);
274  m_Utf8Pos = m_Utf8Buf.begin();
275  return *m_Utf8Pos & 0xFF;
276  }
277  }
278  return (char)c;
279 }
280 
282 {
283  size_t more = 0;
284  TUnicodeSymbol chU = CUtf8::DecodeFirst(c, more);
285  while (chU && more--) {
286  chU = CUtf8::DecodeNext(chU, m_Input.GetChar());
287  }
288  if (chU == 0) {
289  ThrowError(fInvalidData, "invalid UTF8 string");
290  }
291  return chU;
292 }
293 
295 {
296  m_ExpectValue = false;
297  Expect('\"',true);
298  string str;
299  for (;;) {
300  bool encoded = false;
301  char c = ReadEncodedChar(type, encoded);
302  if (!encoded) {
303  if (c == '\r' || c == '\n') {
304  ThrowError(fFormatError, "end of line: expected '\"'");
305  } else if (c == '\"') {
306  break;
307  }
308  }
309  str += char(c);
310  // pre-allocate memory for long strings
311  if ( str.size() > 128 && (double)str.capacity()/((double)str.size()+1.0) < 1.1 ) {
312  str.reserve(str.size()*2);
313  }
314  }
315  str.reserve(str.size());
316  return str;
317 }
318 
319 string CObjectIStreamJson::x_ReadData(EStringType type /*= eStringTypeVisible*/)
320 {
321  SkipWhiteSpace();
322  string str;
323  for (;;) {
324  bool encoded = false;
325  char c = ReadEncodedChar(type, encoded);
326  if (!encoded && strchr(",]} \r\n", c)) {
327  m_Input.UngetChar(c);
328  break;
329  }
330  str += char(c);
331  // pre-allocate memory for long strings
332  if ( str.size() > 128 && (double)str.capacity()/((double)str.size()+1.0) < 1.1 ) {
333  str.reserve(str.size()*2);
334  }
335  }
336  str.reserve(str.size());
337  return str;
338 }
339 
341 {
342  string d(x_ReadData(type));
343  if (d == "null") {
345  }
346  return d;
347 }
348 
350 {
351  m_ExpectValue = false;
352  char to = GetChar(true);
353  for (;;) {
354  bool encoded = false;
355  char c = ReadEncodedChar(eStringTypeUTF8, encoded);
356  if (!encoded) {
357  if (to == '\"') {
358  if (c == to) {
359  break;
360  }
361  }
362  else if (strchr(",]} \r\n", c)) {
363  m_Input.UngetChar(c);
364  break;
365  }
366  }
367  }
368 }
369 
371 {
372  if (!m_RejectedTag.empty()) {
374  m_RejectedTag.erase();
375  } else {
376  SkipWhiteSpace();
378  Expect(':', true);
379  SkipWhiteSpace();
380  }
381  m_ExpectValue = true;
382  return m_LastTag;
383 }
384 
385 string CObjectIStreamJson::ReadValue(EStringType type /*= eStringTypeVisible*/)
386 {
387  return x_ReadString(type);
388 }
389 
390 
392 {
393  if (expect) {
394  Expect(expect, true);
395  }
396  m_BlockStart = true;
397  m_ExpectValue = false;
398 }
399 
401 {
402  if (expect) {
403  Expect(expect, true);
404  }
405  m_BlockStart = false;
406  m_ExpectValue = false;
407 }
408 
410 {
411  if (!m_RejectedTag.empty()) {
412  m_BlockStart = false;
413  return true;
414  }
415  char c = SkipWhiteSpace();
416  if ( m_BlockStart ) {
417  // first element
418  m_BlockStart = false;
419  return c != '}' && c != ']';
420  }
421  else {
422  // next element
423  if ( c == ',' ) {
424  m_Input.SkipChar();
425  return true;
426  }
427  else if ( c != '}' && c != ']' )
428  ThrowError(fFormatError, "',' or '}' or ']' expected");
429  return false;
430  }
431 }
432 
434 {
435  {
436  char c = m_Input.PeekChar();
437  if ((unsigned char)c == 0xEF) {
438  if ((unsigned char)m_Input.PeekChar(1) == 0xBB &&
439  (unsigned char)m_Input.PeekChar(2) == 0xBF) {
440  m_Input.SkipChars(3);
441  }
442  }
443  }
444  m_FileHeader = true;
445  StartBlock('{');
446  string str( ReadKey());
447  if (!StackIsEmpty() && TopFrame().HasTypeInfo()) {
448  const string& tname = TopFrame().GetTypeInfo()->GetName();
449  if (tname.empty()) {
450  UndoClassMember();
451  }
452  if (str != tname) {
453  if (str == NStr::Replace(tname,"-","_")) {
454  return tname;
455  }
456  }
457  }
458  return str;
459 }
460 
462 {
463  EndBlock(m_FileHeader ? '}' : 0);
464  m_FileHeader = false;
466 }
467 
468 
469 
471 {
473 }
474 
476 {
477  x_SkipData();
478 }
479 
481 {
482  return x_ReadDataAndCheck().at(0);
483 }
484 
486 {
487  x_SkipData();
488 }
489 
491 {
493 }
494 
496 {
498 }
499 
501 {
502  x_SkipData();
503 }
504 
506 {
507  x_SkipData();
508 }
509 
511 {
512  char* endptr;
514 }
515 
517 {
518  x_SkipData();
519 }
520 
522  EStringType type /*= eStringTypeVisible*/)
523 {
524  char c = PeekChar(true);
525  if (c == 'n') {
526  if (m_Input.PeekChar(1) == 'u' &&
527  m_Input.PeekChar(2) == 'l' &&
528  m_Input.PeekChar(3) == 'l') {
529  m_ExpectValue = false;
530  m_Input.SkipChars(4);
532  }
533  }
534  s = ReadValue(type);
535 }
536 
538 {
539  x_SkipData();
540 }
541 
543 {
544  if (m_ExpectValue) {
545  x_ReadData();
546  }
547 }
548 
550 {
551  if (m_ExpectValue) {
552  x_SkipData();
553  }
554 }
555 
557 {
558  m_ExpectValue = false;
559  obj.Reset();
560  string value;
561  if (!m_RejectedTag.empty()) {
562  obj.SetName( m_RejectedTag);
563  m_RejectedTag.erase();
564  } else if (!StackIsEmpty() && TopFrame().HasMemberId()) {
565  obj.SetName( TopFrame().GetMemberId().GetName());
566  }
567 
568  if (PeekChar(true) == '{') {
569  ThrowError(fNotImplemented, "Not Implemented");
570 #if 0
571  StartBlock('{');
572  while (NextElement()) {
573  string name = ReadKey();
574  value = ReadValue(eStringTypeUTF8);
575  if (name[0] != '#') {
577  } else {
579  }
580  }
581  EndBlock('}');
582 #endif
583  return;
584  }
585  if (PeekChar(true) == '\"') {
586  value = ReadValue(eStringTypeUTF8);
587  } else {
588  value = x_ReadData();
589  }
591 }
592 
594 {
595  char to = GetChar(true);
596  if (to == '{') {
597  to = '}';
598  } else if (to == '[') {
599  to = ']';
600  } else if (to == '\"') {
601  } else {
602  to = '\n';
603  }
604  for (char c = m_Input.PeekChar(); ; c = m_Input.PeekChar()) {
605  if (to == '\n') {
606  if (c == ',') {
607  return;
608  }
609  }
610  if (c == to) {
611  m_Input.SkipChar();
612  if (c == '\n') {
613  SkipEndOfLine(c);
614  }
615  return;
616  }
617  if (to != '\"') {
618  if (c == '\"' || c == '{' || c == '[') {
619  SkipAnyContent();
620  continue;
621  }
622  }
623 
624  m_Input.SkipChar();
625  if (c == '\n') {
626  SkipEndOfLine(c);
627  }
628  }
629 }
630 
632 {
633  if (!m_RejectedTag.empty()) {
634  m_RejectedTag.erase();
635  }
636  SkipAnyContent();
637 }
638 
640 {
641  m_ExpectValue = false;
642 #if BITSTRING_AS_VECTOR
643  ThrowError(fNotImplemented, "Not Implemented");
644 #else
645  if (IsCompressed()) {
646  ThrowError(fNotImplemented, "Not Implemented");
647  return;
648  }
649  Expect('\"');
650  obj.clear();
651  obj.resize(0);
653  for ( ;; ++len) {
654  char c = GetChar();
655  if (c == '1') {
656  obj.resize(len+1);
657  obj.set_bit(len);
658  } else if (c != '0') {
659  if ( c != 'B' ) {
660  ThrowError(fFormatError, "invalid char in bit string");
661  }
662  break;
663  }
664  }
665  obj.resize(len);
666  Expect('\"');
667 #endif
668 }
669 
671 {
672  CBitString obj;
673  ReadBitString(obj);
674 }
675 
676 
678 {
679  CObjectIStream::ByteBlock block(*this);
680  char buf[4096];
681  while ( block.Read(buf, sizeof(buf)) != 0 )
682  ;
683  block.End();
684 }
685 
687 {
688  m_ExpectValue = false;
690  char c = SkipWhiteSpace();
691  if (c == '\"') {
692  value = values.FindValue( ReadValue());
693  } else {
694  value = (TEnumValueType)ReadInt8();
695  }
696  return value;
697 }
698 
699 #ifdef VIRTUAL_MID_LEVEL_IO
701  const CClassTypeInfo* classType, TObjectPtr classPtr)
702 {
703  ReadClassRandom( classType, classPtr);
704 }
705 
707 {
708  SkipClassRandom(classType);
709 }
710 #endif
711 
712 // container
714 {
715  StartBlock('[');
716 }
717 
719 {
720  EndBlock(']');
721 }
722 
724 {
725  return NextElement();
726 }
728 {
729 }
730 
731 // class
733 {
734  StartBlock((GetStackDepth() > 1 && FetchFrameFromTop(1).GetNotag()) ? 0 : '{');
735 }
736 
738 {
739  m_GotNameless = false;
740  EndBlock((GetStackDepth() > 1 && FetchFrameFromTop(1).GetNotag()) ? 0 : '}');
741 }
742 
744  const CItemsInfo& items, const CTempString& name, bool& deep) const
745 {
746  TMemberIndex i = items.Find(name);
747  if (i != kInvalidMember) {
748  deep = false;
749  return i;
750  }
751  i = items.FindDeep(name, true);
752  if (i != kInvalidMember) {
753  deep = true;
754  return i;
755  }
756 // on writing, we replace hyphens with underscores;
757 // on reading, it complicates our life
758  if (name.find_first_of("_") != CTempString::npos) {
759  TMemberIndex first = items.FirstIndex();
760  TMemberIndex last = items.LastIndex();
761  for (i = first; i <= last; ++i) {
762  const CItemInfo *itemInfo = items.GetItemInfo(i);
763  string item_name = itemInfo->GetId().GetName();
764  NStr::ReplaceInPlace(item_name,"-","_");
765  if (name == item_name) {
766  deep = false;
767  return i;
768  }
769  }
770  for (i = first; i <= last; ++i) {
771  const CItemInfo* itemInfo = items.GetItemInfo(i);
772  const CMemberId& id = itemInfo->GetId();
773  if (id.IsAttlist() || id.HasNotag()) {
774  const CClassTypeInfoBase* classType =
775  dynamic_cast<const CClassTypeInfoBase*>(
777  if (classType) {
778  if (FindDeep(classType->GetItems(), name, deep) != kInvalidMember) {
779  deep = true;
780  return i;
781  }
782  }
783  }
784  }
785  }
786  deep = true;
787  return kInvalidMember;
788 }
789 
791 {
792  TMemberIndex first = classType->GetMembers().FirstIndex();
793  TMemberIndex last = classType->GetMembers().LastIndex();
794 
795  if ( !NextElement() ) {
796  if (!m_GotNameless &&
797  classType->GetMemberInfo(last)->GetId().HasNotag() &&
798  classType->GetMemberInfo(last)->GetTypeInfo()->GetTypeFamily() == eTypeFamilyPrimitive) {
799  TopFrame().SetNotag();
800  m_GotNameless = true;
801  return last;
802  }
803  return kInvalidMember;
804  }
805  m_GotNameless = false;
806 
807  char c = PeekChar();
808  if (m_RejectedTag.empty() && (c == '[' || c == '{')) {
809  for (TMemberIndex i = first; i <= last; ++i) {
810  if (classType->GetMemberInfo(i)->GetId().HasNotag()) {
811  TopFrame().SetNotag();
812  return i;
813  }
814  }
815  }
816  string tagName = ReadKey();
817 
818  if (tagName[0] == '#') {
819  tagName = tagName.substr(1);
820  TopFrame().SetNotag();
821  m_GotNameless = true;
822  }
823 
824  bool deep = false;
825  TMemberIndex ind = FindDeep(classType->GetMembers(), tagName, deep);
826 /*
827  skipping unknown members is not present here
828  this method has to do with random order of members, for example in XML attribute list
829  there is no special marker for end-of-list, so it is "ended" by unknown member.
830  In theory, I could find out memberId and check if it is Attlist
831  If the data type is SET and not attlist, then skipping unknowns can be dangerous
832 */
833  if (deep) {
834  if (ind != kInvalidMember) {
835  TopFrame().SetNotag();
836  }
837  UndoClassMember();
838  }
839  return ind;
840 }
841 
843  TMemberIndex pos)
844 {
845  TMemberIndex first = classType->GetMembers().FirstIndex();
846  TMemberIndex last = classType->GetMembers().LastIndex();
847  if (m_RejectedTag.empty()) {
848  if (pos == first) {
849  if (classType->GetMemberInfo(first)->GetId().IsAttlist()) {
850  TopFrame().SetNotag();
851  return first;
852  }
853  }
854  }
855 
856  if ( !NextElement() ) {
857  if (pos == last &&
858  classType->GetMemberInfo(pos)->GetId().HasNotag() &&
859  classType->GetMemberInfo(pos)->GetTypeInfo()->GetTypeFamily() == eTypeFamilyPrimitive) {
860  TopFrame().SetNotag();
861  return pos;
862  }
863  return kInvalidMember;
864  }
865  char c = PeekChar();
866  if (m_RejectedTag.empty() && (c == '[' || c == '{')) {
867  for (TMemberIndex i = pos; i <= last; ++i) {
868  if (classType->GetMemberInfo(i)->GetId().HasNotag()) {
869  TopFrame().SetNotag();
870  return i;
871  }
872  }
873  }
874  string tagName = ReadKey();
875  if (tagName[0] == '#') {
876  tagName = tagName.substr(1);
877  TopFrame().SetNotag();
878  }
879  bool deep = false;
880  TMemberIndex ind = FindDeep(classType->GetMembers(), tagName, deep);
881  if ( ind == kInvalidMember ) {
882  if (CanSkipUnknownMembers()) {
884  SkipAnyContent();
885  m_ExpectValue = false;
886  return BeginClassMember(classType,pos);
887  } else {
888  UnexpectedMember(tagName, classType->GetMembers());
889  }
890  }
891  if (deep) {
892  if (ind != kInvalidMember) {
893  TopFrame().SetNotag();
894  }
895  UndoClassMember();
896  } else if (ind != kInvalidMember) {
897  if (classType->GetMembers().GetItemInfo(ind)->GetId().HasAnyContent()) {
898  UndoClassMember();
899  }
900  }
901  return ind;
902 }
904 {
905  TopFrame().SetNotag(false);
906 }
907 
909 {
911 }
912 
913 // choice
915 {
916  StartBlock((GetStackDepth() > 1 && FetchFrameFromTop(1).GetNotag()) ? 0 : '{');
917 }
918 
920 {
921  EndBlock((GetStackDepth() > 1 && FetchFrameFromTop(1).GetNotag()) ? 0 : '}');
922 }
923 
925 {
926  if ( !NextElement() )
927  return kInvalidMember;
928  string tagName = ReadKey();
929  bool deep = false;
930  TMemberIndex ind = FindDeep(choiceType->GetVariants(), tagName, deep);
931  if ( ind == kInvalidMember ) {
932  if (CanSkipUnknownVariants()) {
934  } else {
935  UnexpectedMember(tagName, choiceType->GetVariants());
936  }
937  }
938  if (deep) {
939  if (ind != kInvalidMember) {
940  TopFrame().SetNotag();
941  }
942  UndoClassMember();
943  }
944  return ind;
945 }
946 
948 {
949  TopFrame().SetNotag(false);
950 }
951 
952 // byte block
954 {
955  char c = SkipWhiteSpaceAndGetChar();
956  if (c == '\"') {
957  m_Closing = '\"';
958  } else if (c == '[') {
959  m_Closing = ']';
960  } else {
961  ThrowError(fFormatError, "'\"' or '[' expected");
962  }
963 }
964 
966 {
967  Expect(m_Closing);
968  m_Closing = 0;
969 }
970 
972 {
973  char c = m_Input.GetChar();
974  if ( c >= '0' && c <= '9' ) {
975  return c - '0';
976  }
977  else if ( c >= 'A' && c <= 'Z' ) {
978  return c - 'A' + 10;
979  }
980  else if ( c >= 'a' && c <= 'z' ) {
981  return c - 'a' + 10;
982  }
983  else {
984  m_Input.UngetChar(c);
985  }
986  return -1;
987 }
988 
990 {
991  char c = SkipWhiteSpace();
992  if ( (c >= '0' && c <= '9') ||
993  (c >= 'A' && c <= 'Z') ||
994  (c >= 'a' && c <= 'z') ||
995  (c == '+' || c == '/' || c == '=')) {
996  return c;
997  }
998  return -1;
999 }
1000 
1002  ByteBlock& block, char* dst, size_t length)
1003 {
1004  m_ExpectValue = false;
1006  return ReadCustomBytes(block,dst,length);
1007  }
1008  if (IsCompressed()) {
1009  return ReadBase64Bytes( block, dst, length );
1010  }
1011  return ReadHexBytes( block, dst, length );
1012 }
1013 
1015  ByteBlock& block, char* dst, size_t length)
1016 {
1017  if (m_BinaryFormat == eString_Base64) {
1018  return ReadBase64Bytes(block, dst, length);
1019  } else if (m_BinaryFormat == eString_Hex) {
1020  return ReadHexBytes(block, dst, length);
1021  }
1022  bool end_of_data = false;
1023  size_t count = 0;
1024  while ( !end_of_data && length-- > 0 ) {
1025  Uint1 c = 0;
1026  Uint1 mask=0x80;
1027  switch (m_BinaryFormat) {
1028  case eArray_Bool:
1029  for (; !end_of_data && mask!=0; mask = Uint1(mask >> 1)) {
1030  if (ReadBool()) {
1031  c |= mask;
1032  }
1033  end_of_data = !GetChar(',', true);
1034  }
1035  ++count;
1036  *dst++ = c;
1037  break;
1038  case eArray_01:
1039  for (; !end_of_data && mask!=0; mask = Uint1(mask >> 1)) {
1040  if (ReadChar() != '0') {
1041  c |= mask;
1042  }
1043  end_of_data = !GetChar(',', true);
1044  }
1045  ++count;
1046  *dst++ = c;
1047  break;
1048  default:
1049  case eArray_Uint:
1050  c = (Uint1)ReadUint8();
1051  end_of_data = !GetChar(',', true);
1052  ++count;
1053  *dst++ = c;
1054  break;
1055  case eString_01:
1056  case eString_01B:
1057  for (; !end_of_data && mask!=0; mask = Uint1(mask >> 1)) {
1058  char t = GetChar();
1059  end_of_data = t == '\"' || t == 'B';
1060  if (!end_of_data && t != '0') {
1061  c |= mask;
1062  }
1063  if (t == '\"') {
1064  m_Input.UngetChar(t);
1065  }
1066  }
1067  if (mask != 0x40) {
1068  ++count;
1069  *dst++ = c;
1070  }
1071  break;
1072  }
1073  }
1074  if (end_of_data) {
1075  block.EndOfBlock();
1076  }
1077  return count;
1078 }
1079 
1081  ByteBlock& block, char* dst, size_t length)
1082 {
1083  size_t count = 0;
1084  bool end_of_data = false;
1085  const size_t chunk_in = 80;
1086  char src_buf[chunk_in];
1087  size_t bytes_left = length;
1088  size_t src_size, src_read, dst_written;
1089  while (!end_of_data && bytes_left > chunk_in && bytes_left <= length) {
1090  for ( src_size = 0; src_size < chunk_in; ) {
1091  int c = GetBase64Char();
1092  if (c < 0) {
1093  end_of_data = true;
1094  break;
1095  }
1096  /*if (c != '=')*/ {
1097  src_buf[ src_size++ ] = (char)c;
1098  }
1099  m_Input.SkipChar();
1100  }
1101  BASE64_Decode( src_buf, src_size, &src_read,
1102  dst, bytes_left, &dst_written);
1103  if (src_size != src_read) {
1104  ThrowError(fFail, "error decoding base64Binary data");
1105  }
1106  count += dst_written;
1107  bytes_left -= dst_written;
1108  dst += dst_written;
1109  }
1110  if (end_of_data) {
1111  block.EndOfBlock();
1112  }
1113  return count;
1114 }
1115 
1117  ByteBlock& block, char* dst, size_t length)
1118 {
1119  size_t count = 0;
1120  while ( length-- > 0 ) {
1121  int c1 = GetHexChar();
1122  if ( c1 < 0 ) {
1123  block.EndOfBlock();
1124  return count;
1125  }
1126  int c2 = GetHexChar();
1127  if ( c2 < 0 ) {
1128  *dst++ = char(c1 << 4);
1129  count++;
1130  block.EndOfBlock();
1131  return count;
1132  }
1133  else {
1134  *dst++ = char((c1 << 4) | c2);
1135  count++;
1136  }
1137  }
1138  return count;
1139 }
1140 
1141 // char block
1143 {
1144 }
1145 size_t CObjectIStreamJson::ReadChars(CharBlock& /*block*/, char* /*buffer*/, size_t /*count*/)
1146 {
1147  ThrowError(fNotImplemented, "Not Implemented");
1148  return 0;
1149 }
1151 {
1152 }
1153 
1155 {
1156  char c = PeekChar(true);
1157  if (c == 'n') {
1158  string s = x_ReadData();
1159  if (s != "null") {
1160  ThrowError(fFormatError, "null expected");
1161  }
1162  return eNullPointer;
1163  }
1164  return eThisPointer;
1165 }
1166 
1168 {
1169  ThrowError(fNotImplemented, "Not Implemented");
1170  return 0;
1171 }
1172 
1174 {
1175  ThrowError(fNotImplemented, "Not Implemented");
1176  return "";
1177 }
1178 
bitvector with runtime compression of bits.
Definition: bm.h:120
bool IsCompressed(void) const
Definition: objstack.cpp:182
void x_SkipData(void)
virtual void EndClassMember(void)
const CMemberInfo * GetMemberInfo(TMemberIndex index) const
void UnexpectedMember(const CTempString &id, const CItemsInfo &items)
CObjectIStream –.
Definition: objistr.hpp:92
char * buf
Definition: dbpivot.c:60
virtual void SkipBitString(void)
static const unsigned char msg[]
Definition: ccm.c:378
void Expect(char c, bool skipWhiteSpace=false)
bool IsAttlist(void) const
virtual void SkipUNumber(void)
unsigned NCBI_INT8_TYPE Uint8
Unsigned 8 byte sized integer.
Definition: ncbitype.h:146
static string SizetToString(size_t value, TNumToStringFlags flags=0, int base=10)
Convert size_t to string.
Definition: ncbistr.cpp:2649
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:62
TMemberIndex Find(const CTempString &name) const
Definition: memberlist.cpp:242
array of unsigned integers
Definition: objistrjson.hpp:94
virtual TMemberIndex BeginChoiceVariant(const CChoiceTypeInfo *choiceType)
UTF8-encoded string.
Definition: serialdef.hpp:186
virtual void UndoClassMember(void)
EStringType
String type.
Definition: serialdef.hpp:184
static Int8 StringToInt8(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to Int8.
Definition: ncbistr.cpp:694
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3306
size_t ReadHexBytes(ByteBlock &block, char *buffer, size_t count)
MLIOVIR void SkipClassRandom(const CClassTypeInfo *classType)
Definition: objistr.cpp:1396
const CItemsInfo & GetMembers(void) const
const TMemberIndex kInvalidMember
Special value returned from FindMember.
Definition: serialdef.hpp:211
char GetChar(void)
const TFrame & TopFrame(void) const
virtual EPointerType ReadPointerType(void)
virtual void SkipSNumber(void)
virtual void EndContainerElement(void)
bm::id_t size_type
Type used to count bits in the bit vector.
Definition: bm.h:127
size_type find_first_of(const CTempString match, size_type pos=0) const
Find the first occurrence of any character in the matching string within the current string...
Definition: tempstr.hpp:569
string
Definition: cgiapp.hpp:498
void SetName(const string &name)
Set local name.
virtual void EndClass(void)
virtual void BeginChars(CharBlock &block)
signed NCBI_INT8_TYPE Int8
Signed 8 byte sized integer.
Definition: ncbitype.h:143
void SkipChar(void)
Serializable object that stores any combination of parsable data.
Definition: serialbase.hpp:223
void SkipAnyContent(void)
#define ThrowError(flag, mess)
Definition: objstack.hpp:113
virtual const char * what(void) const
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:324
string x_ReadString(EStringType type)
#define kEmptyStr
Definition: ncbistr.hpp:120
const CItemsInfo & GetItems(void) const
virtual void SkipString(EStringType type=eStringTypeVisible)
EBinaryDataFormat
formatting of binary data ('OCTET STRING', 'hexBinary', 'base64Binary')
Definition: objistrjson.hpp:90
virtual void ResetState(void)
Definition: objistr.cpp:463
virtual void ReadAnyContentObject(CAnyContentObject &obj)
int i
TFailFlags SetFailFlags(TFailFlags flags, const char *message=0)
Set fail flags.
Definition: objistr.cpp:528
virtual void BeginBytes(ByteBlock &block)
Keep result finite and normalized: if DBL_MAX < result < INF, result becomes DBL_MAX if 0 < result < ...
Definition: ncbistr.hpp:295
static CObjectIStream * Open(ESerialDataFormat format, CNcbiIstream &inStream, bool deleteInStream)
Create serial object reader and attach it to an input stream.
Definition: objistr.cpp:185
TTypeInfo GetTypeInfo(void) const
virtual void SkipNull(void)
virtual void SkipChar(void)
size_t GetStackDepth(void) const
const CItemInfo * GetItemInfo(TMemberIndex index) const
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:101
static TMemberIndex FirstIndex(void)
Definition: memberlist.hpp:78
unsigned char Uint1
Alias for unsigned char.
Definition: ncbitype.h:117
virtual bool BeginContainerElement(TTypeInfo elementType)
virtual bool ReadBool(void)
Unknown value was present in the input.
Definition: objistr.hpp:396
virtual char ReadChar(void)
virtual void SkipFNumber(void)
TMemberIndex LastIndex(void) const
Definition: memberlist.hpp:82
TMemberIndex FindDeep(const CItemsInfo &items, const CTempString &name, bool &deep) const
virtual void ReadString(string &s, EStringType type=eStringTypeVisible)
bool HasAnyContent(void) const
void UngetChar(char c)
size_t ReadCustomBytes(ByteBlock &block, char *buffer, size_t count)
static CStringUTF8 AsUTF8(const CTempString src, EEncoding encoding, EValidate validate=eNoValidate)
Convert into UTF8 from a C/C++ string.
Definition: ncbistr.hpp:5719
array of 'true' and 'false'
Definition: objistrjson.hpp:92
int TEnumValueType
Definition: serialdef.hpp:206
virtual void EndOfRead(void)
size_t TMemberIndex
Type used for indexing class members and choice variants.
Definition: serialdef.hpp:204
TTypeInfo GetTypeInfo(void) const
size_t TObjectIndex
Definition: objistr.hpp:1011
bool StackIsEmpty(void) const
int GetBase64Char(void)
EEncoding GetDefaultStringEncoding(void) const
Get default encoding of 'string' objects.
void SetDefaultStringEncoding(EEncoding enc)
Set default encoding of 'string' objects If data encoding is different, string will be converted to t...
Definition: objistrjson.cpp:97
void SkipEndOfLine(char lastChar)
Definition: strbuffer.cpp:498
CStringUTF8 m_Utf8Buf
char SkipSpaces(void)
Definition: strbuffer.cpp:206
virtual void ResetState(void)
Definition: objistrjson.cpp:80
static const CTypeInfo * FindRealTypeInfo(const CTypeInfo *info)
Definition: memberlist.cpp:280
static CObjectIStream * CreateObjectIStreamJson(void)
Definition: objistrjson.cpp:43
MLIOVIR void ReadClassRandom(const CClassTypeInfo *classType, TObjectPtr classPtr)
Definition: objistr.cpp:1342
bool HasNotag(void) const
Definition: type.c:8
virtual void ReadBitString(CBitString &obj)
EBinaryDataFormat GetBinaryDataFormat(void) const
Get formatting of binary data.
const CMemberId & GetId(void) const
static TUnicodeSymbol DecodeFirst(char ch, SIZE_TYPE &more)
Begin converting first character of UTF8 sequence into Unicode.
Definition: ncbistr.cpp:7173
void SetValue(const CStringUTF8 &value)
Set normalized value.
void SkipChars(size_t count)
static const char * expect
Definition: tables.c:54
void SetBinaryDataFormat(EBinaryDataFormat fmt)
Set formatting of binary data.
TUnicodeSymbol ReadUtf8Char(char c)
virtual void SkipBool(void)
void SetNotag(bool set=true)
static TUnicodeSymbol DecodeNext(TUnicodeSymbol chU, char ch)
Convert next character of UTF8 sequence into Unicode.
Definition: ncbistr.cpp:7196
virtual void EndContainer(void)
Method is not implemented.
Definition: objistr.hpp:386
virtual double ReadDouble(void)
virtual void EndOfRead(void)
Definition: objistr.cpp:869
string ToString(void) const
Definition: memberid.cpp:113
char ReadEncodedChar(EStringType type, bool &encoded)
#define BASE64_Decode
Definition: ncbi_base64.h:42
TEnumValueType FindValue(const CTempString &name) const
Find numeric value by the name of the enum.
Definition: enumerated.cpp:110
Input file formatting does not conform with specification.
Definition: objistr.hpp:374
virtual void EndChoice(void)
TFrame & FetchFrameFromTop(size_t index)
Root class for all serialization exceptions.
Definition: exception.hpp:49
virtual void BeginClass(const CClassTypeInfo *classInfo)
size_t ReadBase64Bytes(ByteBlock &block, char *buffer, size_t count)
VisibleString (in ASN.1 sense)
Definition: serialdef.hpp:185
virtual string ReadFileHeader(void)
Read file header.
ETypeFamily GetTypeFamily(void) const
string x_ReadDataAndCheck(EStringType type=eStringTypeUTF8)
EEncoding
Definition: ncbistr.hpp:196
char PeekChar(size_t offset=0)
bool CanSkipUnknownMembers(void)
Simple check if it's allowed to skip unknown members.
MLIOVIR void ReadClassSequential(const CClassTypeInfo *classType, TObjectPtr classPtr)
Definition: objistr.cpp:1364
char value[7]
Definition: config.c:428
End of file in the middle of reading an object.
Definition: objistr.hpp:370
virtual size_t ReadBytes(ByteBlock &block, char *buffer, size_t count)
virtual size_t ReadChars(CharBlock &block, char *buffer, size_t count)
CIStreamBuffer m_Input
Definition: objistr.hpp:1029
Internal error, the real reason is unclear.
Definition: objistr.hpp:382
ncbi::TMaskedQueryRegions mask
virtual TObjectIndex ReadObjectPointer(void)
static bool StringToBool(const CTempString str)
Convert string to bool.
Definition: ncbistr.cpp:2715
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3215
static double StringToDoublePosix(const char *str, char **endptr=0, TStringToNumFlags flags=0)
Convert string to double-precision value (analog of strtod function)
Definition: ncbistr.cpp:885
virtual void EndBytes(const ByteBlock &block)
static const size_type npos
Definition: tempstr.hpp:70
bool CanSkipUnknownVariants(void)
Simple check if it's allowed to skip unknown variants.
const string & GetName(void) const
static const char * str(char *buf, int n)
Definition: stats.c:84
static Uint8 StringToUInt8(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to Uint8.
Definition: ncbistr.cpp:774
Input data is incorrect (e.g. invalid enum)
Definition: objistr.hpp:378
virtual void SkipByteBlock(void)
virtual void BeginContainer(const CContainerTypeInfo *containerType)
int len
string ReadValue(EStringType type=eStringTypeVisible)
static TUnicodeSymbol CharToSymbol(char ch, EEncoding encoding)
Convert encoded character into Unicode.
Definition: ncbistr.cpp:7012
string ReadKey(void)
int ReadEscapedChar(bool *encoded=0)
MLIOVIR void SkipClassSequential(const CClassTypeInfo *classType)
Definition: objistr.cpp:1417
const CItemsInfo & GetVariants(void) const
static char SymbolToChar(TUnicodeSymbol sym, EEncoding encoding)
Convert Unicode code point into encoded character.
Definition: ncbistr.cpp:7037
CTypeInfo class contains all information about C++ types (both basic and classes): members and layout...
Definition: typeinfo.hpp:74
void resize(size_type new_size)
Change size of the bvector.
Definition: bm.h:1680
TMemberIndex FindDeep(const CTempString &name, bool search_attlist=false, const CClassTypeInfoBase **classInfo=nullptr) const
Definition: memberlist.cpp:251
virtual TEnumValueType ReadEnum(const CEnumeratedTypeValues &values)
char SkipWhiteSpace(void)
virtual Uint8 ReadUint8(void)
virtual TMemberIndex BeginClassMember(const CClassTypeInfo *classType)
enum ENcbiOwnership EOwnership
Ownership relations between objects.
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string...
Definition: ncbiexpt.hpp:546
bool set_bit(bm::id_t n, bool val=true)
Sets bit n.
Definition: bm.h:965
virtual void ReadNull(void)
virtual Int8 ReadInt8(void)
void clear(bool free_mem=false)
Clears every bit in the bitvector.
Definition: bm.h:1063
char SkipWhiteSpaceAndGetChar(void)
Uint4 TUnicodeSymbol
Unicode character.
Definition: ncbistr.hpp:138
virtual void EndChoiceVariant(void)
CStringUTF8::const_iterator m_Utf8Pos
size_t Read(void *dst, size_t length, bool forceLength=false)
Definition: objistr.cpp:1534
void AddAttribute(const string &name, const string &ns_name, const CStringUTF8 &value)
Add attribute.
void StartBlock(char expect)
CObjectIStreamJson –.
Definition: objistrjson.hpp:53
std::istream & in(std::istream &in_, double &x_)
string x_ReadData(EStringType type=eStringTypeUTF8)
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:147
const string & GetName(void) const
Get name of this type.
Definition: typeinfo.cpp:223
void * TObjectPtr
Definition: serialdef.hpp:55
virtual void SkipAnyContentObject(void)
virtual string GetPosition(void) const
Get current stream position as string.
Definition: objistrjson.cpp:92
EEncoding m_StringEncoding
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:98
virtual void BeginChoice(const CChoiceTypeInfo *choiceType)
void EndBlock(char expect)
EBinaryDataFormat m_BinaryFormat
void SkipEndOfLine(char c)
size_t GetLine(void) const
virtual string ReadOtherPointer(void)
bool NextElement(void)
virtual void EndChars(const CharBlock &block)
string of 0 and 1, plus 'B' at the end
Definition: objistrjson.hpp:97
Modified on Mon Mar 27 16:08:07 2017 by modify_doxy.py rev. 506947