[haiku-development] RFC: BDataIO::Print(), PrintToStream(BDataIO&)

  • From: Ingo Weinhold <ingo_weinhold@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Mon, 29 Jun 2009 19:19:48 +0200

Howdy,

is anyone opposed to the attached patch? Changes are:

* Added BDataIO::[V]Print() methods for convenient printf() style printing 
to BDataIOs.

* Added experimental BFdIO and BFileIO, which are BPositionIO 
implementations wrapping a given file descriptor respectively FILE*.

* Added PrintToStream(BDataIO&) versions to BPoint, BRect, BRegion, 
BMessage.

The new BDataIO methods eat up virtual slots. I suppose Print() could 
actually be non-virtual -- at least I can't imagine why any derived class 
would want to do anything other than the default implementation (i.e. 
construct a va_list and call VPrint()).

The name for VPrint() is "inspired" by the C/POSIX API names. Another 
option would be something more descriptive like PrintVarArgs().

Opinions?

CU, Ingo
Index: headers/os/app/Message.h
===================================================================
--- headers/os/app/Message.h    (revision 31316)
+++ headers/os/app/Message.h    (working copy)
@@ -19,6 +19,7 @@
 #include <TypeConstants.h>     /* For convenience */
 
 class BBlockCache;
+class BDataIO;
 class BMessenger;
 class BHandler;
 class BString;
@@ -68,6 +69,7 @@
                bool                    IsSystem() const;
                bool                    IsReply() const;
                void                    PrintToStream() const;
+               void                    PrintToStream(BDataIO& output) const;
 
                status_t                Rename(const char *oldEntry, const char 
*newEntry);
 
@@ -306,7 +308,8 @@
                ssize_t                 _NativeFlattenedSize() const;
                status_t                _NativeFlatten(char *buffer, ssize_t 
size) const;
                status_t                _NativeFlatten(BDataIO *stream, ssize_t 
*size = NULL) const;
-               void                    _PrintToStream(const char* indent) 
const;
+               void                    _PrintToStream(BDataIO& output,
+                                                       const char* indent) 
const;
 
        private:
                message_header* fHeader;
Index: headers/os/interface/Point.h
===================================================================
--- headers/os/interface/Point.h        (revision 31316)
+++ headers/os/interface/Point.h        (working copy)
@@ -13,6 +13,7 @@
 #include <SupportDefs.h>
 
 
+class BDataIO;
 class BRect;
 
 class BPoint {
@@ -23,13 +24,14 @@
        BPoint();
        BPoint(float X, float Y);
        BPoint(const BPoint &p);
-               
+
        BPoint  &operator=(const BPoint &p);
        void    Set(float X, float Y);
 
        void    ConstrainTo(BRect r);
        void    PrintToStream() const;
-                       
+       void    PrintToStream(BDataIO& output) const;
+
        BPoint  operator-() const;
        BPoint  operator+(const BPoint &p) const;
        BPoint  operator-(const BPoint &p) const;
Index: headers/os/interface/Region.h
===================================================================
--- headers/os/interface/Region.h       (revision 31316)
+++ headers/os/interface/Region.h       (working copy)
@@ -9,6 +9,9 @@
 #include <BeBuild.h>
 #include <Rect.h>
 
+
+class BDataIO;
+
 namespace BPrivate {
        class ServerLink;
        class LinkReceiver;
@@ -56,6 +59,7 @@
                        bool                            Contains(int32 x, int32 
y) const;
 
                        void                            PrintToStream() const;
+                       void                            PrintToStream(BDataIO& 
output) const;
 
                        void                            OffsetBy(int32 x, int32 
y);
 
Index: headers/os/interface/Rect.h
===================================================================
--- headers/os/interface/Rect.h (revision 31316)
+++ headers/os/interface/Rect.h (working copy)
@@ -16,6 +16,9 @@
 #include <math.h>
 
 
+class BDataIO;
+
+
 class BRect {
        public:
                float   left;
@@ -33,6 +36,7 @@
                void    Set(float l, float t, float r, float b);
 
                void    PrintToStream() const;
+               void    PrintToStream(BDataIO& output) const;
 
                BPoint  LeftTop() const;
                BPoint  RightBottom() const;
Index: headers/os/support/DataIO.h
===================================================================
--- headers/os/support/DataIO.h (revision 31316)
+++ headers/os/support/DataIO.h (working copy)
@@ -8,6 +8,7 @@
 #ifndef _DATA_IO_H
 #define _DATA_IO_H
 
+#include <stdarg.h>
 
 #include <SupportDefs.h>
 
@@ -20,12 +21,13 @@
                virtual ssize_t Read(void *buffer, size_t size) = 0;
                virtual ssize_t Write(const void *buffer, size_t size) = 0;
 
+               virtual ssize_t Print(const char* format,...);
+               virtual ssize_t VPrint(const char* format, va_list args);
+
        private:
                BDataIO(const BDataIO &);
                BDataIO &operator=(const BDataIO &);
 
-               virtual void _ReservedDataIO1();
-               virtual void _ReservedDataIO2();
                virtual void _ReservedDataIO3();
                virtual void _ReservedDataIO4();
                virtual void _ReservedDataIO5();
Index: headers/private/storage/FileIO.h
===================================================================
--- headers/private/storage/FileIO.h    (revision 0)
+++ headers/private/storage/FileIO.h    (revision 0)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _FILE_IO_H
+#define _FILE_IO_H
+
+#include <stdio.h>
+
+#include <DataIO.h>
+
+
+class BFileIO : public BPositionIO {
+public:
+                                                               BFileIO(FILE* 
file,
+                                                                       bool 
takeOverOwnership = false);
+       virtual                                         ~BFileIO();
+
+       virtual ssize_t                         Read(void *buffer, size_t size);
+       virtual ssize_t                         Write(const void *buffer, 
size_t size);
+
+       virtual ssize_t                         ReadAt(off_t position, void 
*buffer,
+                                                                       size_t 
size);
+       virtual ssize_t                         WriteAt(off_t position, const 
void *buffer,
+                                                                       size_t 
size);
+
+       virtual off_t                           Seek(off_t position, uint32 
seekMode);
+       virtual off_t                           Position() const;
+
+       virtual status_t                        SetSize(off_t size);
+       virtual status_t                        GetSize(off_t* size) const;
+
+       virtual ssize_t                         VPrint(const char* format, 
va_list args);
+
+private:
+                                                               BFileIO(const 
BFileIO& other);
+                       BFileIO&                        operator=(const 
BFileIO& other);
+
+                       off_t                           _Seek(off_t position, 
uint32 seekMode) const;
+
+private:
+                       FILE*                           fFile;
+                       bool                            fOwnsFile;
+};
+
+
+#endif // _FILE_IO_H
Index: headers/private/storage/FdIO.h
===================================================================
--- headers/private/storage/FdIO.h      (revision 0)
+++ headers/private/storage/FdIO.h      (revision 0)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _FD_IO_H
+#define _FD_IO_H
+
+#include <DataIO.h>
+
+
+class BFdIO : public BPositionIO {
+public:
+                                                               BFdIO(int fd, 
bool takeOverOwnership = false);
+       virtual                                         ~BFdIO();
+
+       virtual ssize_t                         Read(void *buffer, size_t size);
+       virtual ssize_t                         Write(const void *buffer, 
size_t size);
+
+       virtual ssize_t                         ReadAt(off_t position, void 
*buffer,
+                                                                       size_t 
size);
+       virtual ssize_t                         WriteAt(off_t position, const 
void *buffer,
+                                                                       size_t 
size);
+
+       virtual off_t                           Seek(off_t position, uint32 
seekMode);
+       virtual off_t                           Position() const;
+
+       virtual status_t                        SetSize(off_t size);
+       virtual status_t                        GetSize(off_t* size) const;
+
+private:
+                                                               BFdIO(const 
BFdIO& other);
+                       BFdIO&                          operator=(const BFdIO& 
other);
+
+private:
+                       int                                     fFD;
+                       bool                            fOwnsFD;
+};
+
+
+#endif // _FD_IO_H
Index: src/kits/app/Message.cpp
===================================================================
--- src/kits/app/Message.cpp    (revision 31316)
+++ src/kits/app/Message.cpp    (working copy)
@@ -12,6 +12,7 @@
 #include <MessageUtils.h>
 
 #include <DirectMessageTarget.h>
+#include <FileIO.h>
 #include <MessengerPrivate.h>
 #include <TokenSpace.h>
 #include <util/KMessage.h>
@@ -68,19 +69,19 @@
 
 
 template<typename Type> static uint8 *
-print_to_stream_type(uint8* pointer)
+print_to_stream_type(BDataIO& output, uint8* pointer)
 {
        Type *item = (Type *)pointer;
-       item->PrintToStream();
+       item->PrintToStream(output);
        return (uint8 *)(item+1);
 }
 
 
 template<typename Type> static uint8 *
-print_type(const char* format, uint8* pointer)
+print_type(BDataIO& output, const char* format, uint8* pointer)
 {
        Type *item = (Type *)pointer;
-       printf(format, *item, *item);
+       output.Print(format, *item, *item);
        return (uint8 *)(item+1);
 }
 
@@ -500,23 +501,31 @@
 void
 BMessage::PrintToStream() const
 {
-       _PrintToStream("");
-       printf("}\n");
+       BFileIO output(stdout);
+       PrintToStream(output);
 }
 
 
 void
-BMessage::_PrintToStream(const char* indent) const
+BMessage::PrintToStream(BDataIO& output) const
 {
+       _PrintToStream(output, "");
+       output.Print("}\n");
+}
+
+
+void
+BMessage::_PrintToStream(BDataIO& output, const char* indent) const
+{
        DEBUG_FUNCTION_ENTER;
 
        int32 value = B_BENDIAN_TO_HOST_INT32(what);
-       printf("BMessage(");
+       output.Print("BMessage(");
        if (isprint(*(char *)&value)) {
-               printf("'%.4s'", (char *)&value);
+               output.Print("'%.4s'", (char *)&value);
        } else
-               printf("0x%lx", what);
-       printf(") {\n");
+               output.Print("0x%lx", what);
+       output.Print(") {\n");
 
        field_header *field = fFields;
        for (int32 i = 0; i < fHeader->field_count; i++, field++) {
@@ -528,57 +537,65 @@
                uint8 *pointer = fData + field->offset + field->name_length;
                for (int32 j = 0; j < field->count; j++) {
                        if (field->count == 1) {
-                               printf("%s        %s = ", indent,
+                               output.Print("%s        %s = ", indent,
                                        (char *)(fData + field->offset));
                        } else {
-                               printf("%s        %s[%ld] = ", indent,
+                               output.Print("%s        %s[%ld] = ", indent,
                                        (char *)(fData + field->offset), j);
                        }
 
                        switch (field->type) {
                                case B_RECT_TYPE:
-                                       pointer = 
print_to_stream_type<BRect>(pointer);
+                                       pointer = 
print_to_stream_type<BRect>(output, pointer);
                                        break;
 
                                case B_POINT_TYPE:
-                                       pointer = 
print_to_stream_type<BPoint>(pointer);
+                                       pointer = 
print_to_stream_type<BPoint>(output, pointer);
                                        break;
 
                                case B_STRING_TYPE:     {
                                        ssize_t size = *(ssize_t *)pointer;
                                        pointer += sizeof(ssize_t);
-                                       printf("string(\"%s\", %ld bytes)\n", 
(char *)pointer, size);
+                                       output.Print("string(\"%s\", %ld 
bytes)\n", (char *)pointer,
+                                               size);
                                        pointer += size;
                                        break;
                                }
 
                                case B_INT8_TYPE:
-                                       pointer = print_type<int8>("int8(0x%hx 
or %d or \'%.1s\')\n", pointer);
+                                       pointer = print_type<int8>(output,
+                                               "int8(0x%hx or %d or 
\'%.1s\')\n", pointer);
                                        break;
 
                                case B_INT16_TYPE:
-                                       pointer = print_type<int16>("int16 
(0x%x or %d)\n", pointer);
+                                       pointer = print_type<int16>(output,
+                                               "int16 (0x%x or %d)\n", 
pointer);
                                        break;
 
                                case B_INT32_TYPE:
-                                       pointer = 
print_type<int32>("int32(0x%lx or %ld)\n", pointer);
+                                       pointer = print_type<int32>(output, 
"int32(0x%lx or %ld)\n",
+                                               pointer);
                                        break;
 
                                case B_INT64_TYPE:
-                                       pointer = 
print_type<int64>("int64(0x%Lx or %Ld)\n", pointer);
+                                       pointer = print_type<int64>(output, 
"int64(0x%Lx or %Ld)\n",
+                                               pointer);
                                        break;
 
                                case B_BOOL_TYPE:
-                                       printf("bool(%s)\n", *((bool 
*)pointer)!= 0 ? "true" : "false");
+                                       output.Print("bool(%s)\n",
+                                               *((bool*)pointer) != 0 ? "true" 
: "false");
                                        pointer += sizeof(bool);
                                        break;
 
                                case B_FLOAT_TYPE:
-                                       pointer = 
print_type<float>("float(%.4f)\n", pointer);
+                                       pointer = print_type<float>(output, 
"float(%.4f)\n",
+                                               pointer);
                                        break;
 
                                case B_DOUBLE_TYPE:
-                                       pointer = 
print_type<double>("double(%.8f)\n", pointer);
+                                       pointer = print_type<double>(output, 
"double(%.8f)\n",
+                                               pointer);
                                        break;
 
                                case B_REF_TYPE: {
@@ -587,11 +604,11 @@
                                        entry_ref ref;
                                        BPrivate::entry_ref_unflatten(&ref, 
(char *)pointer, size);
 
-                                       printf("entry_ref(device=%ld, 
directory=%lld, name=\"%s\", ",
-                                                       ref.device, 
ref.directory, ref.name);
+                                       output.Print("entry_ref(device=%ld, 
directory=%lld, "
+                                               "name=\"%s\", ", ref.device, 
ref.directory, ref.name);
 
                                        BPath path(&ref);
-                                       printf("path=\"%s\")\n", path.Path());
+                                       output.Print("path=\"%s\")\n", 
path.Path());
                                        pointer += size;
                                        break;
                                }
@@ -608,14 +625,15 @@
                                                fprintf(stderr, "couldn't 
unflatten item %ld\n", i);
                                                break;
                                        }
-                                       message._PrintToStream(buffer);
-                                       printf("%s        }\n", indent);
+                                       message._PrintToStream(output, buffer);
+                                       output.Print("%s        }\n", indent);
                                        pointer += size;
                                        break;
                                }
 
                                default: {
-                                       printf("(type = '%.4s')(size = %ld)\n", 
(char *)&value, size);
+                                       output.Print("(type = '%.4s')(size = 
%ld)\n",
+                                               (char*)&value, size);
                                }
                        }
                }
Index: src/kits/app/Jamfile
===================================================================
--- src/kits/app/Jamfile        (revision 31316)
+++ src/kits/app/Jamfile        (working copy)
@@ -17,7 +17,7 @@
        SubDirC++Flags $(defines) ;
 }
 
-UsePrivateHeaders shared app interface kernel ;
+UsePrivateHeaders app interface kernel shared storage ;
 UsePrivateSystemHeaders ;
 
 SetSubDirSupportedPlatforms haiku libbe_test ;
@@ -55,6 +55,6 @@
        ServerLink.cpp
        ServerMemoryAllocator.cpp
        TokenSpace.cpp
-       TypeConstants.cpp 
+       TypeConstants.cpp
 ;
 
Index: src/kits/interface/Point.cpp
===================================================================
--- src/kits/interface/Point.cpp        (revision 31316)
+++ src/kits/interface/Point.cpp        (working copy)
@@ -14,7 +14,9 @@
 #include <SupportDefs.h>
 #include <Rect.h>
 
+#include <FileIO.h>
 
+
 const BPoint B_ORIGIN(0, 0);
 
 
@@ -29,10 +31,18 @@
 void
 BPoint::PrintToStream() const
 {
-       printf("BPoint(x:%.0f, y:%.0f)\n", x, y);
+       BFileIO output(stdout);
+       PrintToStream(output);
 }
 
 
+void
+BPoint::PrintToStream(BDataIO& output) const
+{
+       output.Print("BPoint(x:%.0f, y:%.0f)\n", x, y);
+}
+
+
 BPoint
 BPoint::operator-() const
 {
Index: src/kits/interface/Region.cpp
===================================================================
--- src/kits/interface/Region.cpp       (revision 31316)
+++ src/kits/interface/Region.cpp       (working copy)
@@ -15,6 +15,8 @@
 
 #include <Debug.h>
 
+#include <FileIO.h>
+
 #include "clipping.h"
 #include "RegionSupport.h"
 
@@ -111,7 +113,7 @@
                fBounds = region.fBounds;
                fCount = region.fCount;
        }
-       
+
        return *this;
 }
 
@@ -125,10 +127,10 @@
 {
        if (&other == this)
                return true;
-       
+
        if (fCount != other.fCount)
                return false;
-       
+
        return memcmp(fData, other.fData, fCount * sizeof(clipping_rect)) == 0;
 }
 
@@ -206,7 +208,7 @@
                const clipping_rect& r = fData[index];
                return BRect(r.left, r.top, r.right - 1, r.bottom - 1);
        }
-       
+
        return BRect();
                // an invalid BRect
 }
@@ -328,11 +330,21 @@
 void
 BRegion::PrintToStream() const
 {
-       Frame().PrintToStream();
+       BFileIO output(stdout);
+       PrintToStream(output);
+}
 
+
+/*!    \brief Prints the BRegion to the given output.
+*/
+void
+BRegion::PrintToStream(BDataIO& output) const
+{
+       Frame().PrintToStream(output);
+
        for (long i = 0; i < fCount; i++) {
                clipping_rect *rect = &fData[i];
-               printf("data[%ld] = BRect(l:%ld.0, t:%ld.0, r:%ld.0, 
b:%ld.0)\n",
+               output.Print("data[%ld] = BRect(l:%ld.0, t:%ld.0, r:%ld.0, 
b:%ld.0)\n",
                        i, rect->left, rect->top, rect->right - 1, rect->bottom 
- 1);
        }
 }
@@ -393,7 +405,7 @@
 {
        if (!valid_rect(rect))
                return;
-               
+
        // convert to internal rect format
        rect.right ++;
        rect.bottom ++;
@@ -442,7 +454,7 @@
 {
        if (!valid_rect(rect))
                return;
-               
+
        // convert to internal rect format
        rect.right ++;
        rect.bottom ++;
@@ -568,7 +580,7 @@
                MakeEmpty();
                return true;
        }
-       
+
        if (!fData) {
                // allocation actually failed
                fDataSize = 0;
Index: src/kits/interface/Jamfile
===================================================================
--- src/kits/interface/Jamfile  (revision 31316)
+++ src/kits/interface/Jamfile  (working copy)
@@ -26,7 +26,7 @@
 SetSubDirSupportedPlatforms haiku libbe_test ;
 
 UseLibraryHeaders agg ;
-UsePrivateHeaders app input print interface shared tracker ;
+UsePrivateHeaders app input print interface shared storage tracker ;
 
 local pngDump ;
 if $(TARGET_PLATFORM) = haiku {
Index: src/kits/interface/Rect.cpp
===================================================================
--- src/kits/interface/Rect.cpp (revision 31316)
+++ src/kits/interface/Rect.cpp (working copy)
@@ -10,7 +10,9 @@
 
 #include <Rect.h>
 
+#include <FileIO.h>
 
+
 void
 BRect::SetLeftTop(const BPoint p)
 {
@@ -208,10 +210,19 @@
 void
 BRect::PrintToStream() const
 {
-       printf("BRect(l:%.1f, t:%.1f, r:%.1f, b:%.1f)\n", left, top, right, 
bottom);
+       BFileIO output(stdout);
+       PrintToStream(output);
 }
 
 
+void
+BRect::PrintToStream(BDataIO& output) const
+{
+       output.Print("BRect(l:%.1f, t:%.1f, r:%.1f, b:%.1f)\n", left, top, 
right,
+               bottom);
+}
+
+
 bool
 BRect::operator==(BRect rect) const
 {
@@ -250,7 +261,7 @@
                return false;
 
        return !(rect.left > right || rect.right < left
-                       || rect.top > bottom || rect.bottom < top);     
+                       || rect.top > bottom || rect.bottom < top);
 }
 
 
Index: src/kits/storage/FdIO.cpp
===================================================================
--- src/kits/storage/FdIO.cpp   (revision 0)
+++ src/kits/storage/FdIO.cpp   (revision 0)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include <FdIO.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+BFdIO::BFdIO(int fd, bool takeOverOwnership)
+       :
+       fFD(fd),
+       fOwnsFD(takeOverOwnership)
+{
+}
+
+
+BFdIO::~BFdIO()
+{
+       if (fOwnsFD)
+               close(fFD);
+}
+
+
+ssize_t
+BFdIO::Read(void *buffer, size_t size)
+{
+       ssize_t bytesRead = read(fFD, buffer, size);
+       return bytesRead >= 0 ? bytesRead : errno;
+}
+
+
+ssize_t
+BFdIO::Write(const void *buffer, size_t size)
+{
+       ssize_t bytesWritten = write(fFD, buffer, size);
+       return bytesWritten >= 0 ? bytesWritten : errno;
+}
+
+
+ssize_t
+BFdIO::ReadAt(off_t position, void *buffer, size_t size)
+{
+       ssize_t bytesRead = pread(fFD, buffer, size, position);
+       return bytesRead >= 0 ? bytesRead : errno;
+}
+
+
+ssize_t
+BFdIO::WriteAt(off_t position, const void *buffer, size_t size)
+{
+       ssize_t bytesWritten = pwrite(fFD, buffer, size, position);
+       return bytesWritten >= 0 ? bytesWritten : errno;
+}
+
+
+off_t
+BFdIO::Seek(off_t position, uint32 seekMode)
+{
+       off_t result = lseek(fFD, position, seekMode);
+       return result >= 0 ? result : errno;
+}
+
+
+off_t
+BFdIO::Position() const
+{
+       off_t result = lseek(fFD, 0, SEEK_CUR);
+       return result >= 0 ? result : errno;
+}
+
+
+status_t
+BFdIO::SetSize(off_t size)
+{
+       return ftruncate(fFD, size) == 0 ? B_OK : errno;
+}
+
+
+status_t
+BFdIO::GetSize(off_t* size) const
+{
+       struct stat st;
+       if (fstat(fFD, &st) < 0)
+               return errno;
+
+       *size = st.st_size;
+       return B_OK;
+}
Index: src/kits/storage/Jamfile
===================================================================
--- src/kits/storage/Jamfile    (revision 31316)
+++ src/kits/storage/Jamfile    (working copy)
@@ -20,7 +20,9 @@
        Directory.cpp
        Entry.cpp
        EntryList.cpp
+       FdIO.cpp
        File.cpp
+       FileIO.cpp
        FindDirectory.cpp
        Mime.cpp
        MimeType.cpp
@@ -75,7 +77,7 @@
        MutablePartition.cpp
        Partition.cpp
        PartitionDelegate.cpp
-       PartitioningInfo.cpp 
+       PartitioningInfo.cpp
        PartitionReference.cpp
 
        CreateChildJob.cpp
Index: src/kits/storage/FileIO.cpp
===================================================================
--- src/kits/storage/FileIO.cpp (revision 0)
+++ src/kits/storage/FileIO.cpp (revision 0)
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include <FileIO.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+
+BFileIO::BFileIO(FILE* file, bool takeOverOwnership)
+       :
+       fFile(file),
+       fOwnsFile(takeOverOwnership)
+{
+}
+
+
+BFileIO::~BFileIO()
+{
+       if (fOwnsFile && fFile != NULL)
+               fclose(fFile);
+}
+
+
+ssize_t
+BFileIO::Read(void *buffer, size_t size)
+{
+       errno = B_OK;
+       ssize_t bytesRead = fread(buffer, 1, size, fFile);
+       return bytesRead >= 0 ? bytesRead : errno;
+}
+
+
+ssize_t
+BFileIO::Write(const void *buffer, size_t size)
+{
+       errno = B_OK;
+       ssize_t bytesRead = fwrite(buffer, 1, size, fFile);
+       return bytesRead >= 0 ? bytesRead : errno;
+}
+
+
+ssize_t
+BFileIO::ReadAt(off_t position, void *buffer, size_t size)
+{
+       // save the old position and seek to the requested one
+       off_t oldPosition = _Seek(position, SEEK_SET);
+       if (oldPosition < 0)
+               return oldPosition;
+
+       // read
+       ssize_t result = BFileIO::Read(buffer, size);
+
+       // seek back
+       fseeko(fFile, oldPosition, SEEK_SET);
+
+       return result;
+}
+
+
+ssize_t
+BFileIO::WriteAt(off_t position, const void *buffer, size_t size)
+{
+       // save the old position and seek to the requested one
+       off_t oldPosition = _Seek(position, SEEK_SET);
+       if (oldPosition < 0)
+               return oldPosition;
+
+       // write
+       ssize_t result = BFileIO::Write(buffer, size);
+
+       // seek back
+       fseeko(fFile, oldPosition, SEEK_SET);
+
+       return result;
+}
+
+
+off_t
+BFileIO::Seek(off_t position, uint32 seekMode)
+{
+       if (fseeko(fFile, position, seekMode) < 0)
+               return errno;
+
+       return BFileIO::Position();
+}
+
+
+off_t
+BFileIO::Position() const
+{
+       off_t result = ftello(fFile);
+       return result >= 0 ? result : errno;
+}
+
+
+status_t
+BFileIO::SetSize(off_t size)
+{
+       return B_UNSUPPORTED;
+}
+
+
+status_t
+BFileIO::GetSize(off_t* _size) const
+{
+       // save the current position and seek to the end
+       off_t position = _Seek(0, SEEK_END);
+       if (position < 0)
+               return position;
+
+       // get the size (position at end) and seek back
+       off_t size = _Seek(position, SEEK_SET);
+       if (size < 0)
+               return size;
+
+       *_size = size;
+       return B_OK;
+}
+
+
+off_t
+BFileIO::_Seek(off_t position, uint32 seekMode) const
+{
+       // save the current position
+       off_t oldPosition = ftello(fFile);
+       if (oldPosition < 0)
+               return errno;
+
+       // seek to the requested position
+       if (fseeko(fFile, position, seekMode) < 0)
+               return errno;
+
+       return oldPosition;
+}
+
+
+ssize_t
+BFileIO::VPrint(const char* format, va_list args)
+{
+       int result = vfprintf(fFile, format, args);
+       return result >= 0 ? result : errno;
+}
Index: src/kits/support/DataIO.cpp
===================================================================
--- src/kits/support/DataIO.cpp (revision 31316)
+++ src/kits/support/DataIO.cpp (working copy)
@@ -24,6 +24,26 @@
 }
 
 
+ssize_t
+BDataIO::Print(const char* format,...)
+{
+       va_list args;
+       va_start(args, format);
+       ssize_t result = VPrint(format, args);
+       va_end(args);
+       return result;
+}
+
+
+ssize_t
+BDataIO::VPrint(const char* format, va_list args)
+{
+       char buffer[1024];
+       int size = vsnprintf(buffer, sizeof(buffer), format, args);
+       return Write(buffer, size);
+}
+
+
 // Private or Reserved
 
 BDataIO::BDataIO(const BDataIO &)
@@ -40,9 +60,34 @@
 }
 
 
+extern "C" ssize_t
+#if __GNUC__ == 2
+_ReservedDataIO1__7BDataIO(BDataIO* dataIO, const char* format,...)
+#else
+_ZN7BDataIO16_ReservedDataIO1Ev(BDataIO* dataIO, const char* format,...)
+#endif
+{
+       va_list args;
+       va_start(args, format);
+       ssize_t result = dataIO->BDataIO::VPrint(format, args);
+       va_end(args);
+       return result;
+}
+
+
+extern "C" ssize_t
+#if __GNUC__ == 2
+_ReservedDataIO2__7BDataIO(BDataIO* dataIO, const char* format, va_list args)
+#else
+_ZN7BDataIO16_ReservedDataIO2Ev(BDataIO* dataIO, const char* format,
+       va_list args)
+#endif
+{
+       return dataIO->BDataIO::VPrint(format, args);
+}
+
+
 // FBC
-void BDataIO::_ReservedDataIO1(){}
-void BDataIO::_ReservedDataIO2(){}
 void BDataIO::_ReservedDataIO3(){}
 void BDataIO::_ReservedDataIO4(){}
 void BDataIO::_ReservedDataIO5(){}
@@ -184,14 +229,14 @@
 
 ssize_t
 BMemoryIO::WriteAt(off_t pos, const void *buffer, size_t size)
-{      
+{
        if (fReadOnly)
                return B_NOT_ALLOWED;
 
        if (buffer == NULL || pos < 0)
                return B_BAD_VALUE;
 
-       ssize_t sizeWritten = 0;        
+       ssize_t sizeWritten = 0;
        if (pos < fBufferSize) {
                sizeWritten = min_c(static_cast<off_t>(size), fBufferSize - 
pos);
                memcpy(fBuffer + pos, buffer, sizeWritten);
@@ -213,13 +258,13 @@
                        break;
                case SEEK_CUR:
                        fPosition += position;
-                       break;          
+                       break;
                case SEEK_END:
                        fPosition = fLength + position;
                        break;
                default:
                        break;
-       }       
+       }
        return fPosition;
 }
 
@@ -366,7 +411,7 @@
                        if (char *newData = static_cast<char*>(realloc(fData, 
newSize))) {
                                // set the new area to 0
                                if (newSize > fMallocSize)
-                                       memset(newData + fMallocSize, 0, 
newSize - fMallocSize);                                
+                                       memset(newData + fMallocSize, 0, 
newSize - fMallocSize);
                                fData = newData;
                                fMallocSize = newSize;
                        } else  // couldn't alloc the memory

Other related posts: