AudioPolicyManager: Convert dump to use String8 (part 1)

Test: dumpsys of APM, diffs.
Bug: 117333182
Change-Id: Ic046acb491efa363423b38a389b046c09ae9d5c9
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
index f86e75a..a948ea9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
@@ -38,7 +38,7 @@
 class AudioRouteVector : public Vector<sp<AudioRoute> >
 {
 public:
-    status_t dump(int fd, int spaces) const;
+    void dump(String8 *dst, int spaces) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioGain.h b/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
index 4ac508f..996347b 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
@@ -18,6 +18,7 @@
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
+#include <utils/String8.h>
 #include <system/audio.h>
 
 namespace android {
@@ -53,7 +54,7 @@
     int getMaxRampInMs() const { return mGain.max_ramp_ms; }
 
     // TODO: remove dump from here (split serialization)
-    void dump(int fd, int spaces, int index) const;
+    void dump(String8 *dst, int spaces, int index) const;
 
     void getDefaultConfig(struct audio_gain_config *config);
     status_t checkConfig(const struct audio_gain_config *config);
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index df3b41e..6e4c044 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -41,7 +41,7 @@
     audio_port_handle_t getId() const;
     audio_module_handle_t getModuleHandle() const;
 
-    status_t    dump(int fd);
+    void dump(String8 *dst) const override;
 
     audio_io_handle_t   mIoHandle = AUDIO_IO_HANDLE_NONE; // input handle
     audio_devices_t     mDevice = AUDIO_DEVICE_NONE;  // current device this input is routed to
@@ -127,7 +127,7 @@
 
     sp<AudioInputDescriptor> getInputForClient(audio_port_handle_t portId);
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 257209a..ed995e0 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -44,7 +44,7 @@
                           AudioPolicyClientInterface *clientInterface);
     virtual ~AudioOutputDescriptor() {}
 
-    status_t    dump(int fd);
+    void dump(String8 *dst) const override;
     void        log(const char* indent);
 
     audio_port_handle_t getId() const;
@@ -150,8 +150,7 @@
                             AudioPolicyClientInterface *clientInterface);
     virtual ~SwAudioOutputDescriptor() {}
 
-    status_t    dump(int fd);
-
+            void dump(String8 *dst) const override;
     virtual audio_devices_t device() const;
     virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
     virtual audio_devices_t supportedDevices();
@@ -207,7 +206,7 @@
                             AudioPolicyClientInterface *clientInterface);
     virtual ~HwAudioOutputDescriptor() {}
 
-    status_t    dump(int fd);
+            void dump(String8 *dst) const override;
 
     virtual audio_devices_t supportedDevices();
     virtual bool setVolume(float volume,
@@ -276,7 +275,7 @@
 
     sp<SwAudioOutputDescriptor> getOutputForClient(audio_port_handle_t portId);
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 class HwAudioOutputCollection :
@@ -290,7 +289,7 @@
      */
     bool isAnyOutputActive(audio_stream_type_t streamToIgnore) const;
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index bd7517f..ebb9352 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -132,7 +132,8 @@
     void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
     const AudioRouteVector &getRoutes() const { return mRoutes; }
 
-    void dump(int fd, int spaces, bool verbose = true) const;
+    void dump(String8 *dst, int spaces, bool verbose = true) const;
+
     void log(const char* indent) const;
 
     AudioGainCollection mGains; // gain controllers
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
index a1ee708..b588d57 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
@@ -112,7 +112,7 @@
 
     bool isDynamic() { return mIsDynamicFormat || mIsDynamicChannels || mIsDynamicRate; }
 
-    void dump(int fd, int spaces) const;
+    void dump(String8 *dst, int spaces) const;
 
 private:
     String8  mName;
@@ -165,7 +165,7 @@
     // One audio profile will be added for each format supported by Audio HAL
     void setFormats(const FormatVector &formats);
 
-    void dump(int fd, int spaces) const;
+    void dump(String8 *dst, int spaces) const;
 
 private:
     sp<AudioProfile> getProfileFor(audio_format_t format) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
index 6b24fde..330f1d4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -46,7 +46,7 @@
 
     audio_route_type_t getType() const { return mType; }
 
-    void dump(int fd, int spaces) const;
+    void dump(String8 *dst, int spaces) const;
 
 private:
     AudioPortVector mSources;
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 8d7914b..68f38dd 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -45,8 +45,7 @@
         mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false) {}
     ~ClientDescriptor() override = default;
 
-    status_t dump(int fd, int spaces, int index);
-    virtual status_t dump(String8& dst, int spaces, int index);
+    virtual void dump(String8 *dst, int spaces, int index) const;
     virtual std::string toShortString() const;
 
     audio_port_handle_t portId() const { return mPortId; }
@@ -72,10 +71,6 @@
     const audio_config_base_t mConfig;
           audio_port_handle_t mPreferredDeviceId;  // selected input device port ID
           bool mActive;
-
-protected:
-    // FIXME: use until other descriptor classes have a dump to String8 method
-    int mDumpFd;
 };
 
 class TrackClientDescriptor: public ClientDescriptor
@@ -90,7 +85,7 @@
     ~TrackClientDescriptor() override = default;
 
     using ClientDescriptor::dump;
-    status_t dump(String8& dst, int spaces, int index) override;
+    void dump(String8 *dst, int spaces, int index) const override;
     std::string toShortString() const override;
 
     audio_output_flags_t flags() const { return mFlags; }
@@ -115,7 +110,7 @@
     ~RecordClientDescriptor() override = default;
 
     using ClientDescriptor::dump;
-    status_t dump(String8& dst, int spaces, int index) override;
+    void dump(String8 *dst, int spaces, int index) const override;
 
     audio_source_t source() const { return mSource; }
     audio_input_flags_t flags() const { return mFlags; }
@@ -146,7 +141,7 @@
     void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
 
     using ClientDescriptor::dump;
-    status_t dump(String8& dst, int spaces, int index) override;
+    void dump(String8 *dst, int spaces, int index) const override;
 
  private:
     const sp<AudioPatch> mPatchDesc;
@@ -159,7 +154,7 @@
     public DefaultKeyedVector< audio_port_handle_t, sp<SourceClientDescriptor> >
 {
 public:
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 typedef std::vector< sp<TrackClientDescriptor> > TrackClientVector;
@@ -191,13 +186,11 @@
     size_t getClientCount() const {
         return mClients.size();
     }
-    String8 dump() const {
-        String8 result;
+    virtual void dump(String8 *dst) const {
         size_t index = 0;
         for (const auto& client: getClientIterable()) {
-            client->dump(result, 2, index++);
+            client->dump(dst, 2, index++);
         }
-        return result;
     }
 
     // helper types
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index c08e752..83fb10c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -51,7 +51,7 @@
     virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
 
     audio_port_handle_t getId() const;
-    status_t dump(int fd, int spaces, int index, bool verbose = true) const;
+    void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
     void log() const;
 
     String8 mAddress;
@@ -85,7 +85,7 @@
     DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
     audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;
 
-    status_t dump(int fd, const String8 &tag, int spaces = 0, bool verbose = true) const;
+    void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
 
 private:
     void refreshTypes();
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 05cfc31..6560431 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -82,7 +82,7 @@
     }
 
     // TODO remove from here (split serialization)
-    void dump(int fd);
+    void dump(String8 *dst) const;
 
 private:
     void refreshSupportedDevices();
@@ -109,7 +109,7 @@
                                              const char *device_name,
                                              bool matchAddress = true) const;
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 67ac9bc..eb32959 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -73,7 +73,7 @@
                              uint32_t flags,
                              bool exactMatchRequiredForInputFlags = false) const;
 
-    void dump(int fd);
+    void dump(String8 *dst) const;
     void log();
 
     bool hasSupportedDevices() const { return !mSupportedDevices.isEmpty(); }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
index ca67b87..c90a582 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
@@ -35,22 +35,16 @@
     return nullptr;
 }
 
-status_t AudioRouteVector::dump(int fd, int spaces) const
+void AudioRouteVector::dump(String8 *dst, int spaces) const
 {
     if (isEmpty()) {
-        return NO_ERROR;
+        return;
     }
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\n%*sAudio Routes (%zu):\n", spaces, "", size());
-    write(fd, buffer, strlen(buffer));
+    dst->appendFormat("\n%*sAudio Routes (%zu):\n", spaces, "", size());
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "%*s- Route %zu:\n", spaces, "", i + 1);
-        write(fd, buffer, strlen(buffer));
-        itemAt(i)->dump(fd, 4);
+        dst->appendFormat("%*s- Route %zu:\n", spaces, "", i + 1);
+        itemAt(i)->dump(dst, 4);
     }
-    return NO_ERROR;
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
index 193d4a6..2725870 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
@@ -98,32 +98,17 @@
     return NO_ERROR;
 }
 
-void AudioGain::dump(int fd, int spaces, int index) const
+void AudioGain::dump(String8 *dst, int spaces, int index) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
+    dst->appendFormat("%*sGain %d:\n", spaces, "", index+1);
+    dst->appendFormat("%*s- mode: %08x\n", spaces, "", mGain.mode);
+    dst->appendFormat("%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
+    dst->appendFormat("%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
+    dst->appendFormat("%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
+    dst->appendFormat("%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
+    dst->appendFormat("%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
+    dst->appendFormat("%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
+    dst->appendFormat("%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 8ef7707..38ad189 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -336,20 +336,16 @@
     return clients;
 }
 
-status_t AudioInputDescriptor::dump(int fd)
+void AudioInputDescriptor::dump(String8 *dst) const
 {
-    String8 result;
-
-    result.appendFormat(" ID: %d\n", getId());
-    result.appendFormat(" Sampling rate: %d\n", mSamplingRate);
-    result.appendFormat(" Format: %d\n", mFormat);
-    result.appendFormat(" Channels: %08x\n", mChannelMask);
-    result.appendFormat(" Devices %08x\n", mDevice);
-    result.append(" AudioRecord Clients:\n");
-    result.append(ClientMapHandler<RecordClientDescriptor>::dump());
-    result.append("\n");
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
+    dst->appendFormat(" ID: %d\n", getId());
+    dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
+    dst->appendFormat(" Format: %d\n", mFormat);
+    dst->appendFormat(" Channels: %08x\n", mChannelMask);
+    dst->appendFormat(" Devices %08x\n", mDevice);
+    dst->append(" AudioRecord Clients:\n");
+    ClientMapHandler<RecordClientDescriptor>::dump(dst);
+    dst->append("\n");
 }
 
 bool AudioInputCollection::isSourceActive(audio_source_t source) const
@@ -421,20 +417,13 @@
     return 0;
 }
 
-status_t AudioInputCollection::dump(int fd) const
+void AudioInputCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nInputs dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nInputs dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        dst->appendFormat("- Input %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
     }
-
-    return NO_ERROR;
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 03685ab..4ce6b08 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -276,36 +276,31 @@
     return clients;
 }
 
-status_t AudioOutputDescriptor::dump(int fd)
+void AudioOutputDescriptor::dump(String8 *dst) const
 {
-    String8 result;
-
-    result.appendFormat(" ID: %d\n", mId);
-    result.appendFormat(" Sampling rate: %d\n", mSamplingRate);
-    result.appendFormat(" Format: %08x\n", mFormat);
-    result.appendFormat(" Channels: %08x\n", mChannelMask);
-    result.appendFormat(" Devices: %08x\n", device());
-    result.appendFormat(" Global active count: %u\n", mGlobalActiveCount);
-    result.append(" Stream volume activeCount muteCount\n");
+    dst->appendFormat(" ID: %d\n", mId);
+    dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
+    dst->appendFormat(" Format: %08x\n", mFormat);
+    dst->appendFormat(" Channels: %08x\n", mChannelMask);
+    dst->appendFormat(" Devices: %08x\n", device());
+    dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
+    dst->append(" Stream volume activeCount muteCount\n");
     for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
-        result.appendFormat(" %02d     %.03f     %02d          %02d\n",
+        dst->appendFormat(" %02d     %.03f     %02d          %02d\n",
                  i, mCurVolume[i], streamActiveCount((audio_stream_type_t)i), mMuteCount[i]);
     }
-    result.append(" AudioTrack Clients:\n");
-    result.append(ClientMapHandler<TrackClientDescriptor>::dump());
-    result.append("\n");
+    dst->append(" AudioTrack Clients:\n");
+    ClientMapHandler<TrackClientDescriptor>::dump(dst);
+    dst->append("\n");
     if (mActiveClients.size() > 0) {
-        result.append(" AudioTrack active (stream) clients:\n");
+        dst->append(" AudioTrack active (stream) clients:\n");
         size_t index = 0;
         for (const auto& clientPair : mActiveClients) {
-            result.appendFormat(" Refcount: %zu", clientPair.second);
-            clientPair.first->dump(result, 2, index++);
+            dst->appendFormat(" Refcount: %zu", clientPair.second);
+            clientPair.first->dump(dst, 2, index++);
         }
-        result.append(" \n");
+        dst->append(" \n");
     }
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
 }
 
 void AudioOutputDescriptor::log(const char* indent)
@@ -328,17 +323,11 @@
     }
 }
 
-status_t SwAudioOutputDescriptor::dump(int fd)
+void SwAudioOutputDescriptor::dump(String8 *dst) const
 {
-    String8 result;
-
-    result.appendFormat(" Latency: %d\n", mLatency);
-    result.appendFormat(" Flags %08x\n", mFlags);
-    write(fd, result.string(), result.size());
-
-    AudioOutputDescriptor::dump(fd);
-
-    return NO_ERROR;
+    dst->appendFormat(" Latency: %d\n", mLatency);
+    dst->appendFormat(" Flags %08x\n", mFlags);
+    AudioOutputDescriptor::dump(dst);
 }
 
 audio_devices_t SwAudioOutputDescriptor::device() const
@@ -609,20 +598,11 @@
 {
 }
 
-status_t HwAudioOutputDescriptor::dump(int fd)
+void HwAudioOutputDescriptor::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    AudioOutputDescriptor::dump(fd);
-
-    snprintf(buffer, SIZE, "Source:\n");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    mSource->dump(fd, 0, 0);
-
-    return NO_ERROR;
+    AudioOutputDescriptor::dump(dst);
+    dst->append("Source:\n");
+    mSource->dump(dst, 0, 0);
 }
 
 audio_devices_t HwAudioOutputDescriptor::supportedDevices()
@@ -792,20 +772,13 @@
     return 0;
 }
 
-status_t SwAudioOutputCollection::dump(int fd) const
+void SwAudioOutputCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nOutputs dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nOutputs dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        dst->appendFormat("- Output %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
     }
-
-    return NO_ERROR;
 }
 
 // HwAudioOutputCollection implementation
@@ -837,20 +810,13 @@
     return false;
 }
 
-status_t HwAudioOutputCollection::dump(int fd) const
+void HwAudioOutputCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nOutputs dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nOutputs dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        dst->appendFormat("- Output %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
     }
-
-    return NO_ERROR;
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 3fe37ab..19dde6a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -354,26 +354,18 @@
     return mGains[index]->checkConfig(gainConfig);
 }
 
-void AudioPort::dump(int fd, int spaces, bool verbose) const
+void AudioPort::dump(String8 *dst, int spaces, bool verbose) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
     if (!mName.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
-        result.append(buffer);
-        write(fd, result.string(), result.size());
+        dst->appendFormat("%*s- name: %s\n", spaces, "", mName.string());
     }
     if (verbose) {
-        mProfiles.dump(fd, spaces);
+        mProfiles.dump(dst, spaces);
 
         if (mGains.size() != 0) {
-            snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
-            result = buffer;
-            write(fd, result.string(), result.size());
+            dst->appendFormat("%*s- gains:\n", spaces, "");
             for (size_t i = 0; i < mGains.size(); i++) {
-                mGains[i]->dump(fd, spaces + 2, i);
+                mGains[i]->dump(dst, spaces + 2, i);
             }
         }
     }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index d04beec..a645e02 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -253,47 +253,35 @@
     return bestMatch > 0 ? NO_ERROR : BAD_VALUE;
 }
 
-void AudioProfile::dump(int fd, int spaces) const
+void AudioProfile::dump(String8 *dst, int spaces) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "",
+    dst->appendFormat("%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "",
              mIsDynamicChannels ? "[dynamic channels]" : "",
              mIsDynamicRate ? "[dynamic rates]" : "");
-    result.append(buffer);
     if (mName.length() != 0) {
-        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
-        result.append(buffer);
+        dst->appendFormat("%*s- name: %s\n", spaces, "", mName.string());
     }
     std::string formatLiteral;
     if (FormatConverter::toString(mFormat, formatLiteral)) {
-        snprintf(buffer, SIZE, "%*s- format: %s\n", spaces, "", formatLiteral.c_str());
-        result.append(buffer);
+        dst->appendFormat("%*s- format: %s\n", spaces, "", formatLiteral.c_str());
     }
     if (!mSamplingRates.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- sampling rates:", spaces, "");
-        result.append(buffer);
+        dst->appendFormat("%*s- sampling rates:", spaces, "");
         for (size_t i = 0; i < mSamplingRates.size(); i++) {
-            snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
-            result.append(buffer);
-            result.append(i == (mSamplingRates.size() - 1) ? "" : ", ");
+            dst->appendFormat("%d", mSamplingRates[i]);
+            dst->append(i == (mSamplingRates.size() - 1) ? "" : ", ");
         }
-        result.append("\n");
+        dst->append("\n");
     }
 
     if (!mChannelMasks.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- channel masks:", spaces, "");
-        result.append(buffer);
+        dst->appendFormat("%*s- channel masks:", spaces, "");
         for (size_t i = 0; i < mChannelMasks.size(); i++) {
-            snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
-            result.append(buffer);
-            result.append(i == (mChannelMasks.size() - 1) ? "" : ", ");
+            dst->appendFormat("0x%04x", mChannelMasks[i]);
+            dst->append(i == (mChannelMasks.size() - 1) ? "" : ", ");
         }
-        result.append("\n");
+        dst->append("\n");
     }
-    write(fd, result.string(), result.size());
 }
 
 ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
@@ -559,17 +547,12 @@
     }
 }
 
-void AudioProfileVector::dump(int fd, int spaces) const
+void AudioProfileVector::dump(String8 *dst, int spaces) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "%*s- Profiles:\n", spaces, "");
-    write(fd, buffer, strlen(buffer));
+    dst->appendFormat("%*s- Profiles:\n", spaces, "");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "%*sProfile %zu:", spaces + 4, "", i);
-        write(fd, buffer, strlen(buffer));
-        itemAt(i)->dump(fd, spaces + 8);
+        dst->appendFormat("%*sProfile %zu:", spaces + 4, "", i);
+        itemAt(i)->dump(dst, spaces + 8);
     }
 }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
index 79ad1f7..c1fe5b0 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -24,29 +24,17 @@
 namespace android
 {
 
-void AudioRoute::dump(int fd, int spaces) const
+void AudioRoute::dump(String8 *dst, int spaces) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*s- Type: %s\n", spaces, "", mType == AUDIO_ROUTE_MUX ? "Mux" : "Mix");
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, "%*s- Sink: %s\n", spaces, "", mSink->getTagName().string());
-    result.append(buffer);
-
+    dst->appendFormat("%*s- Type: %s\n", spaces, "", mType == AUDIO_ROUTE_MUX ? "Mux" : "Mix");
+    dst->appendFormat("%*s- Sink: %s\n", spaces, "", mSink->getTagName().string());
     if (mSources.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- Sources: \n", spaces, "");
-        result.append(buffer);
+        dst->appendFormat("%*s- Sources: \n", spaces, "");
         for (size_t i = 0; i < mSources.size(); i++) {
-            snprintf(buffer, SIZE, "%*s%s \n", spaces + 4, "", mSources[i]->getTagName().string());
-            result.append(buffer);
+            dst->appendFormat("%*s%s \n", spaces + 4, "", mSources[i]->getTagName().string());
         }
     }
-    result.append("\n");
-
-    write(fd, result.string(), result.size());
+    dst->append("\n");
 }
 
 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index c237cef..815612d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -30,21 +30,6 @@
 
 namespace android {
 
-status_t ClientDescriptor::dump(int fd, int spaces, int index)
-{
-    String8 out;
-
-    // FIXME: use until other descriptor classes have a dump to String8 method
-    mDumpFd = fd;
-
-    status_t status = dump(out, spaces, index);
-    if (status == NO_ERROR) {
-        write(fd, out.string(), out.size());
-    }
-
-    return status;
-}
-
 std::string ClientDescriptor::toShortString() const
 {
     std::stringstream ss;
@@ -53,25 +38,21 @@
     return ss.str();
 }
 
-status_t ClientDescriptor::dump(String8& out, int spaces, int index)
+void ClientDescriptor::dump(String8 *dst, int spaces, int index) const
 {
-    out.appendFormat("%*sClient %d:\n", spaces, "", index+1);
-    out.appendFormat("%*s- Port Id: %d Session Id: %d UID: %d\n", spaces, "",
+    dst->appendFormat("%*sClient %d:\n", spaces, "", index+1);
+    dst->appendFormat("%*s- Port Id: %d Session Id: %d UID: %d\n", spaces, "",
              mPortId, mSessionId, mUid);
-    out.appendFormat("%*s- Format: %08x Sampling rate: %d Channels: %08x\n", spaces, "",
+    dst->appendFormat("%*s- Format: %08x Sampling rate: %d Channels: %08x\n", spaces, "",
              mConfig.format, mConfig.sample_rate, mConfig.channel_mask);
-    out.appendFormat("%*s- Preferred Device Id: %08x\n", spaces, "", mPreferredDeviceId);
-    out.appendFormat("%*s- State: %s\n", spaces, "", mActive ? "Active" : "Inactive");
-    return NO_ERROR;
+    dst->appendFormat("%*s- Preferred Device Id: %08x\n", spaces, "", mPreferredDeviceId);
+    dst->appendFormat("%*s- State: %s\n", spaces, "", mActive ? "Active" : "Inactive");
 }
 
-status_t TrackClientDescriptor::dump(String8& out, int spaces, int index)
+void TrackClientDescriptor::dump(String8 *dst, int spaces, int index) const
 {
-    ClientDescriptor::dump(out, spaces, index);
-
-    out.appendFormat("%*s- Stream: %d flags: %08x\n", spaces, "", mStream, mFlags);
-
-    return NO_ERROR;
+    ClientDescriptor::dump(dst, spaces, index);
+    dst->appendFormat("%*s- Stream: %d flags: %08x\n", spaces, "", mStream, mFlags);
 }
 
 std::string TrackClientDescriptor::toShortString() const
@@ -82,13 +63,10 @@
     return ss.str();
 }
 
-status_t RecordClientDescriptor::dump(String8& out, int spaces, int index)
+void RecordClientDescriptor::dump(String8 *dst, int spaces, int index) const
 {
-    ClientDescriptor::dump(out, spaces, index);
-
-    out.appendFormat("%*s- Source: %d flags: %08x\n", spaces, "", mSource, mFlags);
-
-    return NO_ERROR;
+    ClientDescriptor::dump(dst, spaces, index);
+    dst->appendFormat("%*s- Source: %d flags: %08x\n", spaces, "", mSource, mFlags);
 }
 
 SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
@@ -112,31 +90,19 @@
     mHwOutput = hwOutput;
 }
 
-status_t SourceClientDescriptor::dump(String8& out, int spaces, int index)
+void SourceClientDescriptor::dump(String8 *dst, int spaces, int index) const
 {
-    TrackClientDescriptor::dump(out, spaces, index);
-
-    if (mDumpFd >= 0) {
-        out.appendFormat("%*s- Device:\n", spaces, "");
-        write(mDumpFd, out.string(), out.size());
-
-        mSrcDevice->dump(mDumpFd, 2, 0);
-        mDumpFd = -1;
-    }
-
-    return NO_ERROR;
+    TrackClientDescriptor::dump(dst, spaces, index);
+    dst->appendFormat("%*s- Device:\n", spaces, "");
+    mSrcDevice->dump(dst, 2, 0);
 }
 
-status_t SourceClientCollection::dump(int fd) const
+void SourceClientCollection::dump(String8 *dst) const
 {
-    String8 out;
-    out.append("\nAudio sources:\n");
-    write(fd, out.string(), out.size());
+    dst->append("\nAudio sources:\n");
     for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->dump(fd, 2, i);
+        valueAt(i)->dump(dst, 2, i);
     }
-
-    return NO_ERROR;
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 1638645..a9f7220 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -199,20 +199,15 @@
     return nullptr;
 }
 
-status_t DeviceVector::dump(int fd, const String8 &tag, int spaces, bool verbose) const
+void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbose) const
 {
     if (isEmpty()) {
-        return NO_ERROR;
+        return;
     }
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "%*s- %s devices:\n", spaces, "", tag.string());
-    write(fd, buffer, strlen(buffer));
+    dst->appendFormat("%*s- %s devices:\n", spaces, "", tag.string());
     for (size_t i = 0; i < size(); i++) {
-        itemAt(i)->dump(fd, spaces + 2, i, verbose);
+        itemAt(i)->dump(dst, spaces + 2, i, verbose);
     }
-    return NO_ERROR;
 }
 
 void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -269,35 +264,23 @@
     port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
 }
 
-status_t DeviceDescriptor::dump(int fd, int spaces, int index, bool verbose) const
+void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
-    result.append(buffer);
+    dst->appendFormat("%*sDevice %d:\n", spaces, "", index + 1);
     if (mId != 0) {
-        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
-        result.append(buffer);
+        dst->appendFormat("%*s- id: %2d\n", spaces, "", mId);
     }
     if (!mTagName.isEmpty()) {
-        snprintf(buffer, SIZE, "%*s- tag name: %s\n", spaces, "", mTagName.string());
-        result.append(buffer);
+        dst->appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.string());
     }
     std::string deviceLiteral;
     if (deviceToString(mDeviceType, deviceLiteral)) {
-        snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
-        result.append(buffer);
+        dst->appendFormat("%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
     }
     if (mAddress.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
-        result.append(buffer);
+        dst->appendFormat("%*s- address: %-32s\n", spaces, "", mAddress.string());
     }
-    write(fd, result.string(), result.size());
-    AudioPort::dump(fd, spaces, verbose);
-
-    return NO_ERROR;
+    AudioPort::dump(dst, spaces, verbose);
 }
 
 void DeviceDescriptor::log() const
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index dcc0ec8..92bc595 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -218,37 +218,27 @@
     mHandle = handle;
 }
 
-void HwModule::dump(int fd)
+void HwModule::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "  - name: %s\n", getName());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - version: %u.%u\n", getHalVersionMajor(), getHalVersionMinor());
-    result.append(buffer);
-    write(fd, result.string(), result.size());
+    dst->appendFormat("  - name: %s\n", getName());
+    dst->appendFormat("  - handle: %d\n", mHandle);
+    dst->appendFormat("  - version: %u.%u\n", getHalVersionMajor(), getHalVersionMinor());
     if (mOutputProfiles.size()) {
-        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
+        dst->append("  - outputs:\n");
         for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    output %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mOutputProfiles[i]->dump(fd);
+            dst->appendFormat("    output %zu:\n", i);
+            mOutputProfiles[i]->dump(dst);
         }
     }
     if (mInputProfiles.size()) {
-        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
+        dst->append("  - inputs:\n");
         for (size_t i = 0; i < mInputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    input %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mInputProfiles[i]->dump(fd);
+            dst->appendFormat("    input %zu:\n", i);
+            mInputProfiles[i]->dump(dst);
         }
     }
-    mDeclaredDevices.dump(fd, String8("Declared"),  2, true);
-    mRoutes.dump(fd, 2);
+    mDeclaredDevices.dump(dst, String8("Declared"), 2, true);
+    mRoutes.dump(dst, 2);
 }
 
 sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
@@ -301,19 +291,13 @@
     return devDesc;
 }
 
-status_t HwModuleCollection::dump(int fd) const
+void HwModuleCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nHW Modules dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nHW Modules dump:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1);
-        write(fd, buffer, strlen(buffer));
-        itemAt(i)->dump(fd);
+        dst->appendFormat("- HW Module %zu:\n", i + 1);
+        itemAt(i)->dump(dst);
     }
-    return NO_ERROR;
 }
 
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fbc2384..8660624 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -108,16 +108,11 @@
     return true;
 }
 
-void IOProfile::dump(int fd)
+void IOProfile::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
+    AudioPort::dump(dst, 4);
 
-    AudioPort::dump(fd, 4);
-
-    snprintf(buffer, SIZE, "    - flags: 0x%04x", getFlags());
-    result.append(buffer);
+    dst->appendFormat("    - flags: 0x%04x", getFlags());
     std::string flagsLiteral;
     if (getRole() == AUDIO_PORT_ROLE_SINK) {
         InputFlagConverter::maskToString(getFlags(), flagsLiteral);
@@ -125,21 +120,14 @@
         OutputFlagConverter::maskToString(getFlags(), flagsLiteral);
     }
     if (!flagsLiteral.empty()) {
-        result.appendFormat(" (%s)", flagsLiteral.c_str());
+        dst->appendFormat(" (%s)", flagsLiteral.c_str());
     }
-    result.append("\n");
-    write(fd, result.string(), result.size());
-    mSupportedDevices.dump(fd, String8("Supported"), 4, false);
-
-    result.clear();
-    snprintf(buffer, SIZE, "\n    - maxOpenCount: %u - curOpenCount: %u\n",
+    dst->append("\n");
+    mSupportedDevices.dump(dst, String8("Supported"), 4, false);
+    dst->appendFormat("\n    - maxOpenCount: %u - curOpenCount: %u\n",
              maxOpenCount, curOpenCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "    - maxActiveCount: %u - curActiveCount: %u\n",
+    dst->appendFormat("    - maxActiveCount: %u - curActiveCount: %u\n",
              maxActiveCount, curActiveCount);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
 }
 
 void IOProfile::log()
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5ea82a7..21f893a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2707,32 +2707,33 @@
     result.appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
     result.appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
     result.appendFormat(" Config source: %s\n", getConfig().getSource().c_str());
+    mAvailableOutputDevices.dump(&result, String8("Available output"));
+    mAvailableInputDevices.dump(&result, String8("Available input"));
+    mHwModulesAll.dump(&result);
+    mOutputs.dump(&result);
+    mInputs.dump(&result);
     write(fd, result.string(), result.size());
 
-    mAvailableOutputDevices.dump(fd, String8("Available output"));
-    mAvailableInputDevices.dump(fd, String8("Available input"));
-    mHwModulesAll.dump(fd);
-    mOutputs.dump(fd);
-    mInputs.dump(fd);
+    // TODO convert these to dump to string.
     mVolumeCurves->dump(fd);
     mEffects.dump(fd);
     mAudioPatches.dump(fd);
     mPolicyMixes.dump(fd);
-    mAudioSources.dump(fd);
 
+    result.clear();
+    mAudioSources.dump(&result);
     if (!mSurroundFormats.empty()) {
-        result = String8("\nEnabled Surround Formats:\n");
+        result.append("\nEnabled Surround Formats:\n");
         size_t i = 0;
         for (const auto& fmt : mSurroundFormats) {
             result.append(i++ == 0 ? "  " : ", ");
             std::string sfmt;
             FormatConverter::toString(fmt, sfmt);
-            result.appendFormat("%s", sfmt.c_str());
+            result.append(sfmt.c_str());
         }
         result.append("\n");
-        write(fd, result.string(), result.size());
     }
-
+    write(fd, result.string(), result.size());
     return NO_ERROR;
 }