Athena IO Library
IStreamReader.hpp
1 #ifndef ISTREAMREADER_HPP
2 #define ISTREAMREADER_HPP
3 
4 #include <memory>
5 #include <functional>
6 #include "utf8proc.h"
7 #include "IStream.hpp"
8 
9 namespace athena
10 {
11 namespace io
12 {
18 class IStreamReader : public IStream
19 {
20 public:
21  virtual ~IStreamReader() {}
22 
28  virtual void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current)=0;
29 
32  inline void seekAlign64() {seek(ROUND_UP_64(position()), SeekOrigin::Begin);}
33 
36  inline void seekAlign32() {seek(ROUND_UP_32(position()), SeekOrigin::Begin);}
37 
40  inline void seekAlign16() {seek(ROUND_UP_16(position()), SeekOrigin::Begin); }
41 
46  inline bool atEnd() const
47  {return position() >= length();}
48 
53  virtual atUint64 position() const=0;
54 
59  virtual atUint64 length() const=0;
60 
65  inline atInt8 readByte() {atInt8 val; readUBytesToBuf(&val, 1); return val;}
66  template <class T>
67  inline atInt8 readVal(typename std::enable_if<std::is_same<T, atInt8>::value>::type* = 0)
68  {return readByte();}
69  template <class T>
70  inline atInt8 readValLittle(typename std::enable_if<std::is_same<T, atInt8>::value>::type* = 0)
71  {return readByte();}
72  template <class T>
73  inline atInt8 readValBig(typename std::enable_if<std::is_same<T, atInt8>::value>::type* = 0)
74  {return readByte();}
75 
80  inline atUint8 readUByte() {return readByte();}
81  template <class T>
82  inline atUint8 readVal(typename std::enable_if<std::is_same<T, atUint8>::value>::type* = 0)
83  {return readUByte();}
84  template <class T>
85  inline atUint8 readValLittle(typename std::enable_if<std::is_same<T, atUint8>::value>::type* = 0)
86  {return readUByte();}
87  template <class T>
88  inline atUint8 readValBig(typename std::enable_if<std::is_same<T, atUint8>::value>::type* = 0)
89  {return readUByte();}
90 
95  inline std::unique_ptr<atInt8[]> readBytes(atUint64 length)
96  {
97  atInt8* buf = new atInt8[length];
98  readUBytesToBuf(buf, length);
99  return std::unique_ptr<atInt8[]>(buf);
100  }
101 
106  inline std::unique_ptr<atUint8[]> readUBytes(atUint64 length)
107  {
108  atUint8* buf = new atUint8[length];
109  readUBytesToBuf(buf, length);
110  return std::unique_ptr<atUint8[]>(buf);
111  }
112 
118  inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);}
119 
120 
127  virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0;
128 
134  inline atInt16 readInt16()
135  {
136  atInt16 val;
137  readUBytesToBuf(&val, 2);
138  return m_endian == BigEndian ? utility::BigInt16(val) : utility::LittleInt16(val);
139  }
140  template <class T>
141  inline atInt16 readVal(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
142  {return readInt16();}
143 
149  inline atInt16 readInt16Little()
150  {
151  atInt16 val;
152  readUBytesToBuf(&val, 2);
153  return utility::LittleInt16(val);
154  }
155  template <class T>
156  inline atInt16 readValLittle(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
157  {return readInt16Little();}
158 
164  inline atInt16 readInt16Big()
165  {
166  atInt16 val;
167  readUBytesToBuf(&val, 2);
168  return utility::BigInt16(val);
169  }
170  template <class T>
171  inline atInt16 readValBig(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
172  {return readInt16Big();}
173 
179  inline atUint16 readUint16()
180  {return readInt16();}
181  template <class T>
182  inline atUint16 readVal(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
183  {return readUint16();}
184 
190  inline atUint16 readUint16Little()
191  {
192  atUint16 val;
193  readUBytesToBuf(&val, 2);
194  return utility::LittleUint16(val);
195  }
196  template <class T>
197  inline atUint16 readValLittle(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
198  {return readUint16Little();}
199 
205  inline atUint16 readUint16Big()
206  {
207  atUint16 val;
208  readUBytesToBuf(&val, 2);
209  return utility::BigUint16(val);
210  }
211  template <class T>
212  inline atUint16 readValBig(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
213  {return readUint16Big();}
214 
220  inline atInt32 readInt32()
221  {
222  atInt32 val;
223  readUBytesToBuf(&val, 4);
224  return m_endian == BigEndian ? utility::BigInt32(val) : utility::LittleInt32(val);
225  }
226  template <class T>
227  inline atInt32 readVal(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
228  {return readInt32();}
229 
235  inline atInt32 readInt32Little()
236  {
237  atInt32 val;
238  readUBytesToBuf(&val, 4);
239  return utility::LittleInt32(val);
240  }
241  template <class T>
242  inline atInt32 readValLittle(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
243  {return readInt32Little();}
244 
250  inline atInt32 readInt32Big()
251  {
252  atInt32 val;
253  readUBytesToBuf(&val, 4);
254  return utility::BigInt32(val);
255  }
256  template <class T>
257  inline atInt32 readValBig(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
258  {return readInt32Big();}
259 
265  inline atUint32 readUint32()
266  {return readInt32();}
267  template <class T>
268  inline atUint32 readVal(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
269  {return readUint32();}
270 
276  inline atUint32 readUint32Little()
277  {
278  atUint32 val;
279  readUBytesToBuf(&val, 4);
280  return utility::LittleUint32(val);
281  }
282  template <class T>
283  inline atInt32 readValLittle(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
284  {return readUint32Little();}
285 
291  inline atUint32 readUint32Big()
292  {
293  atUint32 val;
294  readUBytesToBuf(&val, 4);
295  return utility::BigUint32(val);
296  }
297  template <class T>
298  inline atUint32 readValBig(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
299  {return readUint32Big();}
300 
306  inline atInt64 readInt64()
307  {
308  atInt64 val;
309  readUBytesToBuf(&val, 8);
310  return m_endian == BigEndian ? utility::BigInt64(val) : utility::LittleInt64(val);
311  }
312  template <class T>
313  inline atInt64 readVal(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
314  {return readInt64();}
315 
321  inline atInt64 readInt64Little()
322  {
323  atInt64 val;
324  readUBytesToBuf(&val, 8);
325  return utility::LittleInt64(val);
326  }
327  template <class T>
328  inline atInt64 readValLittle(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
329  {return readInt64Little();}
330 
336  inline atInt64 readInt64Big()
337  {
338  atInt64 val;
339  readUBytesToBuf(&val, 8);
340  return utility::BigInt64(val);
341  }
342  template <class T>
343  inline atInt64 readValBig(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
344  {return readInt64Big();}
345 
351  inline atUint64 readUint64()
352  {return readInt64();}
353  template <class T>
354  inline atUint64 readVal(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
355  {return readUint64();}
356 
362  inline atUint64 readUint64Little()
363  {
364  atUint64 val;
365  readUBytesToBuf(&val, 8);
366  return utility::LittleUint64(val);
367  }
368  template <class T>
369  inline atUint64 readValLittle(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
370  {return readUint64Little();}
371 
377  inline atUint64 readUint64Big()
378  {
379  atUint64 val;
380  readUBytesToBuf(&val, 8);
381  return utility::BigUint64(val);
382  }
383  template <class T>
384  inline atUint64 readValBig(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
385  {return readUint64Big();}
386 
392  inline float readFloat()
393  {
394  float val;
395  readUBytesToBuf(&val, 4);
396  return m_endian == BigEndian ? utility::BigFloat(val) : utility::LittleFloat(val);
397  }
398  template <class T>
399  inline float readVal(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
400  {return readFloat();}
401 
407  inline float readFloatLittle()
408  {
409  float val;
410  readUBytesToBuf(&val, 4);
411  return utility::LittleFloat(val);
412  }
413  template <class T>
414  inline float readValLittle(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
415  {return readFloatLittle();}
416 
422  inline float readFloatBig()
423  {
424  float val;
425  readUBytesToBuf(&val, 4);
426  return utility::BigFloat(val);
427  }
428  template <class T>
429  inline float readValBig(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
430  {return readFloatBig();}
431 
437  inline double readDouble()
438  {
439  double val;
440  readUBytesToBuf(&val, 8);
441  return m_endian == BigEndian ? utility::BigDouble(val) : utility::LittleDouble(val);
442  }
443  template <class T>
444  inline double readVal(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
445  {return readDouble();}
446 
452  inline double readDoubleLittle()
453  {
454  double val;
455  readUBytesToBuf(&val, 8);
456  return utility::LittleDouble(val);
457  }
458  template <class T>
459  inline double readValLittle(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
460  {return readDoubleLittle();}
461 
467  inline double readDoubleBig()
468  {
469  double val;
470  readUBytesToBuf(&val, 8);
471  return utility::BigDouble(val);
472  }
473  template <class T>
474  inline double readValBig(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
475  {return readDoubleBig();}
476 
481  inline bool readBool()
482  {
483  atUint8 val;
484  readUBytesToBuf(&val, 1);
485  return val != 0;
486  }
487  template <class T>
488  inline bool readVal(typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
489  {return readBool();}
490  template <class T>
491  inline bool readValLittle(typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
492  {return readBool();}
493  template <class T>
494  inline bool readValBig(typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
495  {return readBool();}
496 
503  {
504  atVec2f val;
505  readUBytesToBuf(&val, 8);
506  if (m_endian == BigEndian)
507  {
508  utility::BigFloat(val.vec[0]);
509  utility::BigFloat(val.vec[1]);
510  }
511  else
512  {
513  utility::LittleFloat(val.vec[0]);
514  utility::LittleFloat(val.vec[1]);
515  }
516  return val;
517  }
518  template <class T>
519  inline atVec2f readVal(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
520  {return readVec2f();}
521 
528  {
529  atVec2f val;
530  readUBytesToBuf(&val, 8);
531  utility::LittleFloat(val.vec[0]);
532  utility::LittleFloat(val.vec[1]);
533  return val;
534  }
535  template <class T>
536  inline atVec2f readValLittle(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
537  {return readVec2fLittle();}
538 
545  {
546  atVec2f val;
547  readUBytesToBuf(&val, 8);
548  utility::BigFloat(val.vec[0]);
549  utility::BigFloat(val.vec[1]);
550  return val;
551  }
552  template <class T>
553  inline atVec2f readValBig(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
554  {return readVec2fBig();}
555 
562  {
563  atVec3f val;
564  readUBytesToBuf(&val, 12);
565  if (m_endian == BigEndian)
566  {
567  utility::BigFloat(val.vec[0]);
568  utility::BigFloat(val.vec[1]);
569  utility::BigFloat(val.vec[2]);
570  }
571  else
572  {
573  utility::LittleFloat(val.vec[0]);
574  utility::LittleFloat(val.vec[1]);
575  utility::LittleFloat(val.vec[2]);
576  }
577  return val;
578  }
579  template <class T>
580  inline atVec3f readVal(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
581  {return readVec3f();}
582 
589  {
590  atVec3f val;
591  readUBytesToBuf(&val, 12);
592  utility::LittleFloat(val.vec[0]);
593  utility::LittleFloat(val.vec[1]);
594  utility::LittleFloat(val.vec[2]);
595  return val;
596  }
597  template <class T>
598  inline atVec3f readValLittle(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
599  {return readVec3fLittle();}
600 
607  {
608  atVec3f val;
609  readUBytesToBuf(&val, 12);
610  utility::BigFloat(val.vec[0]);
611  utility::BigFloat(val.vec[1]);
612  utility::BigFloat(val.vec[2]);
613  return val;
614  }
615  template <class T>
616  inline atVec3f readValBig(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
617  {return readVec3fBig();}
618 
625  {
626  atVec4f val;
627  readUBytesToBuf(&val, 16);
628  if (m_endian == BigEndian)
629  {
630  utility::BigFloat(val.vec[0]);
631  utility::BigFloat(val.vec[1]);
632  utility::BigFloat(val.vec[2]);
633  utility::BigFloat(val.vec[3]);
634  }
635  else
636  {
637  utility::LittleFloat(val.vec[0]);
638  utility::LittleFloat(val.vec[1]);
639  utility::LittleFloat(val.vec[2]);
640  utility::LittleFloat(val.vec[3]);
641  }
642  return val;
643  }
644  template <class T>
645  inline atVec4f readVal(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
646  {return readVec4f();}
647 
654  {
655  atVec4f val;
656  readUBytesToBuf(&val, 16);
657  utility::LittleFloat(val.vec[0]);
658  utility::LittleFloat(val.vec[1]);
659  utility::LittleFloat(val.vec[2]);
660  utility::LittleFloat(val.vec[3]);
661  return val;
662  }
663  template <class T>
664  inline atVec4f readValLittle(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
665  {return readVec4fLittle();}
666 
673  {
674  atVec4f val;
675  readUBytesToBuf(&val, 16);
676  utility::BigFloat(val.vec[0]);
677  utility::BigFloat(val.vec[1]);
678  utility::BigFloat(val.vec[2]);
679  utility::BigFloat(val.vec[3]);
680  return val;
681  }
682  template <class T>
683  inline atVec4f readValBig(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
684  {return readVec4fBig();}
685 
692  {
693  atVec2d val;
694  readUBytesToBuf(&val, 16);
695  if (m_endian == BigEndian)
696  {
697  utility::BigDouble(val.vec[0]);
698  utility::BigDouble(val.vec[1]);
699  }
700  else
701  {
702  utility::LittleDouble(val.vec[0]);
703  utility::LittleDouble(val.vec[1]);
704  }
705  return val;
706  }
707  template <class T>
708  inline atVec2d readVal(typename std::enable_if<std::is_same<T, atVec2d>::value>::type* = 0)
709  {return readVec2d();}
710 
717  {
718  atVec2d val;
719  readUBytesToBuf(&val, 16);
720  utility::LittleDouble(val.vec[0]);
721  utility::LittleDouble(val.vec[1]);
722  return val;
723  }
724  template <class T>
725  inline atVec2d readValLittle(typename std::enable_if<std::is_same<T, atVec2d>::value>::type* = 0)
726  {return readVec2dLittle();}
727 
734  {
735  atVec2d val;
736  readUBytesToBuf(&val, 16);
737  utility::BigDouble(val.vec[0]);
738  utility::BigDouble(val.vec[1]);
739  return val;
740  }
741  template <class T>
742  inline atVec2d readValBig(typename std::enable_if<std::is_same<T, atVec2d>::value>::type* = 0)
743  {return readVec2dBig();}
744 
751  {
752  atVec3d val;
753  readUBytesToBuf(&val, 24);
754  if (m_endian == BigEndian)
755  {
756  utility::BigDouble(val.vec[0]);
757  utility::BigDouble(val.vec[1]);
758  utility::BigDouble(val.vec[2]);
759  }
760  else
761  {
762  utility::LittleDouble(val.vec[0]);
763  utility::LittleDouble(val.vec[1]);
764  utility::LittleDouble(val.vec[2]);
765  }
766  return val;
767  }
768  template <class T>
769  inline atVec3d readVal(typename std::enable_if<std::is_same<T, atVec3d>::value>::type* = 0)
770  {return readVec3d();}
771 
778  {
779  atVec3d val;
780  readUBytesToBuf(&val, 24);
781  utility::LittleDouble(val.vec[0]);
782  utility::LittleDouble(val.vec[1]);
783  utility::LittleDouble(val.vec[2]);
784  return val;
785  }
786  template <class T>
787  inline atVec3d readValLittle(typename std::enable_if<std::is_same<T, atVec3d>::value>::type* = 0)
788  {return readVec3dLittle();}
789 
796  {
797  atVec3d val;
798  readUBytesToBuf(&val, 24);
799  utility::BigDouble(val.vec[0]);
800  utility::BigDouble(val.vec[1]);
801  utility::BigDouble(val.vec[2]);
802  return val;
803  }
804  template <class T>
805  inline atVec3d readValBig(typename std::enable_if<std::is_same<T, atVec3d>::value>::type* = 0)
806  {return readVec3dBig();}
807 
814  {
815  atVec4d val;
816  readUBytesToBuf(&val, 32);
817  if (m_endian == BigEndian)
818  {
819  utility::BigDouble(val.vec[0]);
820  utility::BigDouble(val.vec[1]);
821  utility::BigDouble(val.vec[2]);
822  utility::BigDouble(val.vec[3]);
823  }
824  else
825  {
826  utility::LittleDouble(val.vec[0]);
827  utility::LittleDouble(val.vec[1]);
828  utility::LittleDouble(val.vec[2]);
829  utility::LittleDouble(val.vec[3]);
830  }
831  return val;
832  }
833  template <class T>
834  inline atVec4d readVal(typename std::enable_if<std::is_same<T, atVec4d>::value>::type* = 0)
835  {return readVec4d();}
836 
843  {
844  atVec4d val;
845  readUBytesToBuf(&val, 32);
846  utility::LittleDouble(val.vec[0]);
847  utility::LittleDouble(val.vec[1]);
848  utility::LittleDouble(val.vec[2]);
849  utility::LittleDouble(val.vec[3]);
850  return val;
851  }
852  template <class T>
853  inline atVec4d readValLittle(typename std::enable_if<std::is_same<T, atVec4d>::value>::type* = 0)
854  {return readVec4dLittle();}
855 
862  {
863  atVec4d val;
864  readUBytesToBuf(&val, 32);
865  utility::BigDouble(val.vec[0]);
866  utility::BigDouble(val.vec[1]);
867  utility::BigDouble(val.vec[2]);
868  utility::BigDouble(val.vec[3]);
869  return val;
870  }
871  template <class T>
872  inline atVec4d readValBig(typename std::enable_if<std::is_same<T, atVec4d>::value>::type* = 0)
873  {return readVec4dBig();}
874 
881  inline std::string readWStringAsString(atInt32 fixedLen = -1)
882  {
883  if (fixedLen == 0)
884  return std::string();
885 
886  std::string retval;
887  atUint16 chr = readUint16();
888 
889  atInt32 i;
890  for (i=0 ;; ++i)
891  {
892  if (fixedLen >= 0 && i >= fixedLen - 1)
893  break;
894 
895  if (!chr)
896  break;
897 
898  utf8proc_uint8_t mb[4];
899  utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(chr), mb);
900  if (c < 0)
901  {
902  atWarning("invalid UTF-8 character while encoding");
903  return retval;
904  }
905 
906  retval.append(reinterpret_cast<char*>(mb), c);
907  chr = readUint16();
908  }
909 
910  if (fixedLen >= 0 && i < fixedLen)
911  seek(fixedLen - i);
912 
913  return retval;
914  }
915 
922  inline std::string readWStringAsStringLittle(atInt32 fixedLen = -1)
923  {
924  if (fixedLen == 0)
925  return std::string();
926 
927  std::string retval;
928  atUint16 chr = readUint16Little();
929 
930  atInt32 i;
931  for (i=0 ;; ++i)
932  {
933  if (fixedLen >= 0 && i >= fixedLen - 1)
934  break;
935 
936  if (!chr)
937  break;
938 
939  utf8proc_uint8_t mb[4];
940  utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(chr), mb);
941  if (c < 0)
942  {
943  atWarning("invalid UTF-8 character while encoding");
944  return retval;
945  }
946 
947  retval.append(reinterpret_cast<char*>(mb), c);
948  chr = readUint16Little();
949  }
950 
951  if (fixedLen >= 0 && i < fixedLen)
952  seek(fixedLen - i);
953 
954  return retval;
955  }
956 
963  inline std::string readWStringAsStringBig(atInt32 fixedLen = -1)
964  {
965  if (fixedLen == 0)
966  return std::string();
967 
968  std::string retval;
969  atUint16 chr = readUint16Big();
970 
971  atInt32 i;
972  for (i = 0 ;; ++i)
973  {
974  if (fixedLen >= 0 && i >= fixedLen - 1)
975  break;
976 
977  if (!chr)
978  break;
979 
980  utf8proc_uint8_t mb[4];
981  utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(chr), mb);
982  if (c < 0)
983  {
984  atWarning("invalid UTF-8 character while encoding");
985  return retval;
986  }
987 
988  retval.append(reinterpret_cast<char*>(mb), c);
989  chr = readUint16Big();
990  }
991 
992  if (fixedLen >= 0 && i < fixedLen)
993  seek(fixedLen - i);
994 
995  return retval;
996  }
997 
1003  inline std::string readString(atInt32 fixedLen = -1)
1004  {
1005  if (fixedLen == 0)
1006  return std::string();
1007  std::string ret;
1008  atUint8 chr = readByte();
1009 
1010  atInt32 i;
1011  for (i = 1 ; chr != 0 ; ++i)
1012  {
1013  ret += chr;
1014 
1015  if (fixedLen >= 0 && i >= fixedLen)
1016  break;
1017 
1018  chr = readByte();
1019  }
1020 
1021  if (fixedLen >= 0 && i < fixedLen)
1022  seek(fixedLen - i);
1023 
1024  return ret;
1025  }
1026  template <class T>
1027  inline std::string readVal(typename std::enable_if<std::is_same<T, std::string>::value>::type* = 0)
1028  {return readString();}
1029 
1035  inline std::wstring readWString(atInt32 fixedLen = -1)
1036  {
1037  if (fixedLen == 0)
1038  return std::wstring();
1039 
1040  std::wstring ret;
1041  atUint16 chr = readUint16();
1042 
1043  atInt32 i;
1044  for (i = 1 ; chr != 0 ; ++i)
1045  {
1046  ret += chr;
1047 
1048  if (fixedLen >= 0 && i >= fixedLen)
1049  break;
1050 
1051  chr = readUint16();
1052  }
1053 
1054  if (fixedLen >= 0 && i < fixedLen)
1055  seek(fixedLen - i);
1056 
1057  return ret;
1058  }
1059  template <class T>
1060  inline std::wstring readVal(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
1061  {return readWString();}
1062 
1069  inline std::wstring readWStringLittle(atInt32 fixedLen = -1)
1070  {
1071  if (fixedLen == 0)
1072  return std::wstring();
1073 
1074  std::wstring ret;
1075  atUint16 chr = readUint16Little();
1076 
1077  atInt32 i;
1078  for (i = 1 ; chr != 0 ; ++i)
1079  {
1080  ret += chr;
1081 
1082  if (fixedLen >= 0 && i >= fixedLen)
1083  break;
1084 
1085  chr = readUint16Little();
1086  }
1087 
1088  if (fixedLen >= 0 && i < fixedLen)
1089  seek(fixedLen - i);
1090 
1091  return ret;
1092  }
1093  template <class T>
1094  inline std::wstring readValLittle(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
1095  {return readWStringLittle();}
1096 
1103  inline std::wstring readWStringBig(atInt32 fixedLen = -1)
1104  {
1105  if (fixedLen == 0)
1106  return std::wstring();
1107  std::wstring ret;
1108  atUint16 chr = readUint16Big();
1109 
1110  atInt32 i;
1111  for (i = 1 ; chr != 0 ; ++i)
1112  {
1113  ret += chr;
1114 
1115  if (fixedLen >= 0 && i >= fixedLen)
1116  break;
1117 
1118  chr = readUint16Big();
1119  }
1120 
1121  if (fixedLen >= 0 && i < fixedLen)
1122  seek(fixedLen - i);
1123 
1124  return ret;
1125  }
1126  template <class T>
1127  inline std::wstring readValBig(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
1128  {return readWStringBig();}
1129 
1137  template<class T>
1138  void enumerate(std::vector<T>& vector, size_t count,
1139  typename std::enable_if<std::is_arithmetic<T>::value ||
1140  std::is_same<T, atVec2f>::value ||
1141  std::is_same<T, atVec3f>::value ||
1142  std::is_same<T, atVec4f>::value>::type* = 0)
1143  {
1144  vector.clear();
1145  vector.reserve(count);
1146  for (size_t i=0 ; i<count ; ++i)
1147  vector.push_back(readVal<T>());
1148  }
1149 
1157  template<class T>
1158  void enumerateLittle(std::vector<T>& vector, size_t count,
1159  typename std::enable_if<std::is_arithmetic<T>::value ||
1160  std::is_same<T, atVec2f>::value ||
1161  std::is_same<T, atVec3f>::value ||
1162  std::is_same<T, atVec4f>::value>::type* = 0)
1163  {
1164  vector.clear();
1165  vector.reserve(count);
1166  for (size_t i=0 ; i<count ; ++i)
1167  vector.push_back(readValLittle<T>());
1168  }
1169 
1177  template<class T>
1178  void enumerateBig(std::vector<T>& vector, size_t count,
1179  typename std::enable_if<std::is_arithmetic<T>::value ||
1180  std::is_same<T, atVec2f>::value ||
1181  std::is_same<T, atVec3f>::value ||
1182  std::is_same<T, atVec4f>::value>::type* = 0)
1183  {
1184  vector.clear();
1185  vector.reserve(count);
1186  for (size_t i=0 ; i<count ; ++i)
1187  vector.push_back(readValBig<T>());
1188  }
1189 
1195  template<class T>
1196  void enumerate(std::vector<T>& vector, size_t count,
1197  typename std::enable_if<!std::is_arithmetic<T>::value &&
1198  !std::is_same<T, atVec2f>::value &&
1199  !std::is_same<T, atVec3f>::value &&
1200  !std::is_same<T, atVec4f>::value>::type* = 0)
1201  {
1202  vector.clear();
1203  vector.reserve(count);
1204  for (size_t i=0 ; i<count ; ++i)
1205  {
1206  vector.emplace_back();
1207  vector.back().read(*this);
1208  }
1209  }
1210 
1218  template<class T>
1219  void enumerate(std::vector<T>& vector, size_t count, std::function<void(IStreamReader&, T&)> readf)
1220  {
1221  vector.clear();
1222  vector.reserve(count);
1223  for (size_t i=0 ; i<count ; ++i)
1224  {
1225  vector.emplace_back();
1226  readf(*this, vector.back());
1227  }
1228  }
1229 };
1230 template <typename T>
1231 IStreamReader& operator>>(IStreamReader& lhs, T& rhs)
1232 {
1233  rhs = lhs.readVal<T>();
1234  return lhs;
1235 }
1236 }
1237 }
1238 #endif // ISTREAMREADER
1239 
atUint8 readUByte()
Reads a byte at the current position and advances the current position.
void seekAlign32()
Sets the buffers position relative to the next 32-byte aligned position.
atInt32 readInt32()
Reads a Int32 and swaps to endianness specified by setEndian depending on platform and advances the c...
atInt8 readByte()
Reads a byte at the current position and advances the current position.
std::unique_ptr< atInt8[]> readBytes(atUint64 length)
Reads a byte at the current position and advances the current position.
std::string readWStringAsString(atInt32 fixedLen=-1)
Reads a wide-char string (using endianness from setEndian), converts to UTF8 and advances the positio...
std::wstring readWString(atInt32 fixedLen=-1)
Reads a wstring and advances the position in the file.
atVec3f readVec3fBig()
Reads an atVec3f (12 bytes), swaps against big endianness depending on platform and advances the curr...
double readDoubleBig()
Reads a double and swaps against big endianness depending on platform and advances the current positi...
atUint32 readUint32Little()
Reads a Uint32 and swaps against little endianness depending on platform and advances the current pos...
atVec2d readVec2d()
Reads an atVec2d (16 bytes), swaps to endianness specified by setEndian depending on platform and adv...
atVec4f readVec4fLittle()
Reads an atVec4f (16 bytes), swaps against little endianness depending on platform and advances the c...
void enumerate(std::vector< T > &vector, size_t count, std::function< void(IStreamReader &, T &)> readf)
Performs lambda-assisted std::vector enumeration reads using type T.
atInt32 readInt32Big()
Reads a Int32 and swaps against big endianness depending on platform and advances the current positio...
atInt64 readInt64Little()
Reads a Int64 and swaps against little endianness depending on platform and advances the current posi...
atVec3f readVec3f()
Reads an atVec3f (12 bytes), swaps to endianness specified by setEndian depending on platform and adv...
The IStreamReader class defines a basic API for reading from streams, Implementors are provided with ...
atVec4d readVec4dBig()
Reads an atVec4d (32 bytes), swaps against big endianness depending on platform and advances the curr...
std::wstring readWStringLittle(atInt32 fixedLen=-1)
Reads a wstring assuming little-endian characters and advances the position in the file...
float readFloatBig()
Reads a float and swaps against big endianness depending on platform and advances the current positio...
atVec3d readVec3dBig()
Reads an atVec3d (24 bytes), swaps against big endianness depending on platform and advances the curr...
atVec2d readVec2dBig()
Reads an atVec2d (16 bytes), swaps against big endianness depending on platform and advances the curr...
atVec2f readVec2fLittle()
Reads an atVec2f (8 bytes), swaps against little endianness depending on platform and advances the cu...
float readFloat()
Reads a float and swaps to endianness specified by setEndian depending on platform and advances the c...
std::string readWStringAsStringBig(atInt32 fixedLen=-1)
Reads a wide-char string (against big-endian), converts to UTF8 and advances the position in the file...
atUint16 readUint16Big()
Reads a Uint16 and swaps against big endianness depending on platform and advances the current positi...
atInt16 readInt16Little()
Reads a Int16 and swaps against little endianness depending on platform and advances the current posi...
atUint64 readUint64()
Reads a Uint64 and swaps to endianness specified by setEndian depending on platform and advances the ...
atInt64 readInt64()
Reads a Int64 and swaps to endianness specified by setEndian depending on platform and advances the c...
std::string readString(atInt32 fixedLen=-1)
Reads a string and advances the position in the file.
std::wstring readWStringBig(atInt32 fixedLen=-1)
Reads a wstring assuming big-endian characters and advances the position in the file.
atInt16 readInt16()
Reads a Int16 and swaps to endianness specified by setEndian depending on platform and advances the c...
virtual atUint64 position() const =0
Returns the current position in the stream.
atVec4d readVec4d()
Reads an atVec4d (32 bytes), swaps to endianness specified by setEndian depending on platform and adv...
atUint16 readUint16Little()
Reads a Uint16 and swaps against little endianness depending on platform and advances the current pos...
atVec3d readVec3dLittle()
Reads an atVec3d (24 bytes), swaps against little endianness depending on platform and advances the c...
virtual void seek(atInt64 pos, SeekOrigin origin=SeekOrigin::Current)=0
Sets the buffers position relative to the specified position. It seeks relative to the current posit...
atVec4f readVec4f()
Reads an atVec4f (16 bytes), swaps to endianness specified by setEndian depending on platform and adv...
atUint32 readUint32Big()
Reads a Uint32 and swaps against big endianness depending on platform and advances the current positi...
atVec4d readVec4dLittle()
Reads an atVec4d (32 bytes), swaps against little endianness depending on platform and advances the c...
std::unique_ptr< atUint8[]> readUBytes(atUint64 length)
Reads a byte at the current position and advances the current position.
void enumerateBig(std::vector< T > &vector, size_t count, typename std::enable_if< std::is_arithmetic< T >::value||std::is_same< T, atVec2f >::value||std::is_same< T, atVec3f >::value||std::is_same< T, atVec4f >::value >::type *=0)
Performs automatic std::vector enumeration reads using numeric type T.
atVec3f readVec3fLittle()
Reads an atVec3f (12 bytes), swaps against little endianness depending on platform and advances the c...
atUint64 readUint64Big()
Reads a Uint64 and swaps against big endianness depending on platform and advances the current positi...
void seekAlign64()
Sets the buffer&#39;s position relative to the next 64-byte aligned position.
atVec3d readVec3d()
Reads an atVec3d (24 bytes), swaps to endianness specified by setEndian depending on platform and adv...
bool readBool()
Reads a bool and advances the current position.
atUint64 readUint64Little()
Reads a Uint64 and swaps against little endianness depending on platform and advances the current pos...
atUint64 readBytesToBuf(void *buf, atUint64 len)
Attempts to read a fixed length of data into a pre-allocated buffer.
atInt32 readInt32Little()
Reads a Int32 and swaps against little endianness depending on platform and advances the current posi...
void enumerateLittle(std::vector< T > &vector, size_t count, typename std::enable_if< std::is_arithmetic< T >::value||std::is_same< T, atVec2f >::value||std::is_same< T, atVec3f >::value||std::is_same< T, atVec4f >::value >::type *=0)
Performs automatic std::vector enumeration reads using numeric type T.
std::string readWStringAsStringLittle(atInt32 fixedLen=-1)
Reads a wide-char string (against little-endian), converts to UTF8 and advances the position in the f...
atInt16 readInt16Big()
Reads a Int16 and swaps against big endianness depending on platform and advances the current positio...
virtual atUint64 length() const =0
Returns the length of the file.
atUint32 readUint32()
Reads a Uint32 and swaps to endianness specified by setEndian depending on platform and advances the ...
atVec2f readVec2fBig()
Reads an atVec2f (8 bytes), swaps against big endianness depending on platform and advances the curre...
void enumerate(std::vector< T > &vector, size_t count, typename std::enable_if< std::is_arithmetic< T >::value||std::is_same< T, atVec2f >::value||std::is_same< T, atVec3f >::value||std::is_same< T, atVec4f >::value >::type *=0)
Performs automatic std::vector enumeration reads using numeric type T.
bool atEnd() const
Returns whether or not the stream is at the end.
void enumerate(std::vector< T > &vector, size_t count, typename std::enable_if<!std::is_arithmetic< T >::value &&!std::is_same< T, atVec2f >::value &&!std::is_same< T, atVec3f >::value &&!std::is_same< T, atVec4f >::value >::type *=0)
Performs automatic std::vector enumeration reads using non-numeric type T.
atVec4f readVec4fBig()
Reads an atVec4f (16 bytes), swaps against big endianness depending on platform and advances the curr...
atVec2d readVec2dLittle()
Reads an atVec2d (16 bytes), swaps against little endianness depending on platform and advances the c...
atInt64 readInt64Big()
Reads a Int64 and swaps against big endianness depending on platform and advances the current positio...
float readFloatLittle()
Reads a float and swaps against little endianness depending on platform and advances the current posi...
double readDouble()
Reads a double and swaps to endianness specified by setEndian depending on platform and advances the ...
atUint16 readUint16()
Reads a Uint16 and swaps to endianness specified by setEndian depending on platform and advances the ...
void seekAlign16()
Sets the buffer&#39;s position relative to the next 16-byte aligned position.
virtual atUint64 readUBytesToBuf(void *buf, atUint64 len)=0
Attempts to read a fixed length of data into a pre-allocated buffer, this function is client defined ...
atVec2f readVec2f()
Reads an atVec2f (8 bytes), swaps to endianness specified by setEndian depending on platform and adva...
double readDoubleLittle()
Reads a double and swaps against little endianness depending on platform and advances the current pos...