Home | History | Annotate | Download | only in ustl-1.0
      1 // This file is part of the ustl library, an STL implementation.
      2 //
      3 // Copyright (C) 2005 by Mike Sharov <msharov (at) users.sourceforge.net>
      4 // This file is free software, distributed under the MIT License.
      5 //
      6 // cmemlink.cc
      7 //
      8 // See cmemlink.h for documentation.
      9 //
     10 
     11 #include "cmemlink.h"
     12 #include "ofstream.h"
     13 #include "strmsize.h"
     14 #include "ualgo.h"
     15 #include "uassert.h"
     16 
     17 #if PLATFORM_ANDROID
     18 #include <stdio.h>
     19 #undef CPU_HAS_MMX
     20 #endif
     21 
     22 namespace ustl {
     23 
     24 /// \brief Attaches the object to pointer \p p of size \p n.
     25 ///
     26 /// If \p p is NULL and \p n is non-zero, bad_alloc is thrown and current
     27 /// state remains unchanged.
     28 ///
     29 void cmemlink::link (const void* p, size_type n)
     30 {
     31     if (!p && n)
     32 #if PLATFORM_ANDROID
     33        printf("bad alloc\n");
     34 #else /* !PLATFORM_ANDROID */
     35 	throw bad_alloc (n);
     36 #endif
     37     unlink();
     38     relink (p, n);
     39 }
     40 
     41 /// Writes the object to stream \p os
     42 void cmemlink::write (ostream& os) const
     43 {
     44     const written_size_type sz (size());
     45     assert (sz == size() && "No support for writing memblocks larger than 4G");
     46     os << sz;
     47     os.write (cdata(), sz);
     48     os.align (alignof (sz));
     49 }
     50 
     51 /// Writes the object to stream \p os
     52 void cmemlink::text_write (ostringstream& os) const
     53 {
     54     os.write (begin(), readable_size());
     55 }
     56 
     57 /// Returns the number of bytes required to write this object to a stream.
     58 cmemlink::size_type cmemlink::stream_size (void) const
     59 {
     60     const written_size_type sz (size());
     61     return (Align (stream_size_of (sz) + sz, alignof(sz)));
     62 }
     63 
     64 /// Writes the data to file \p "filename".
     65 void cmemlink::write_file (const char* filename, int mode) const
     66 {
     67     fstream f;
     68     f.exceptions (fstream::allbadbits);
     69     f.open (filename, fstream::out | fstream::trunc, mode);
     70     f.write (cdata(), readable_size());
     71     f.close();
     72 }
     73 
     74 /// swaps the contents with \p l
     75 void cmemlink::swap (cmemlink& l)
     76 {
     77 #if CPU_HAS_MMX && SIZE_OF_POINTER == 4
     78     asm (
     79 	"movq %0, %%mm0\n\t"
     80 	"movq %2, %%mm1\n\t"
     81 	"movq %%mm0, %2\n\t"
     82 	"movq %%mm1, %0"
     83 	: "=m"(m_Data), "=m"(m_Size), "=m"(l.m_Data), "=m"(l.m_Size)
     84 	:
     85 	: "mm0", "mm1", "st", "st(1)");
     86     simd::reset_mmx();
     87 #elif CPU_HAS_SSE && SIZE_OF_POINTER == 8
     88     asm (
     89 	"movups %0, %%xmm0\n\t"
     90 	"movups %2, %%xmm1\n\t"
     91 	"movups %%xmm0, %2\n\t"
     92 	"movups %%xmm1, %0"
     93 	: "=m"(m_Data), "=m"(m_Size), "=m"(l.m_Data), "=m"(l.m_Size)
     94 	:
     95 	: "xmm0", "xmm1");
     96 #else
     97     ::ustl::swap (m_Data, l.m_Data);
     98     ::ustl::swap (m_Size, l.m_Size);
     99 #endif
    100 }
    101 
    102 /// Compares to memory block pointed by l. Size is compared first.
    103 bool cmemlink::operator== (const cmemlink& l) const
    104 {
    105     return (l.m_Size == m_Size &&
    106 	    (l.m_Data == m_Data || 0 == memcmp (l.m_Data, m_Data, m_Size)));
    107 }
    108 
    109 } // namespace ustl
    110 
    111