1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/unicode/bytestream.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,257 @@ 1.4 +// Copyright (C) 2009-2012, International Business Machines 1.5 +// Corporation and others. All Rights Reserved. 1.6 +// 1.7 +// Copyright 2007 Google Inc. All Rights Reserved. 1.8 +// Author: sanjay@google.com (Sanjay Ghemawat) 1.9 +// 1.10 +// Abstract interface that consumes a sequence of bytes (ByteSink). 1.11 +// 1.12 +// Used so that we can write a single piece of code that can operate 1.13 +// on a variety of output string types. 1.14 +// 1.15 +// Various implementations of this interface are provided: 1.16 +// ByteSink: 1.17 +// CheckedArrayByteSink Write to a flat array, with bounds checking 1.18 +// StringByteSink Write to an STL string 1.19 + 1.20 +// This code is a contribution of Google code, and the style used here is 1.21 +// a compromise between the original Google code and the ICU coding guidelines. 1.22 +// For example, data types are ICU-ified (size_t,int->int32_t), 1.23 +// and API comments doxygen-ified, but function names and behavior are 1.24 +// as in the original, if possible. 1.25 +// Assertion-style error handling, not available in ICU, was changed to 1.26 +// parameter "pinning" similar to UnicodeString. 1.27 +// 1.28 +// In addition, this is only a partial port of the original Google code, 1.29 +// limited to what was needed so far. The (nearly) complete original code 1.30 +// is in the ICU svn repository at icuhtml/trunk/design/strings/contrib 1.31 +// (see ICU ticket 6765, r25517). 1.32 + 1.33 +#ifndef __BYTESTREAM_H__ 1.34 +#define __BYTESTREAM_H__ 1.35 + 1.36 +/** 1.37 + * \file 1.38 + * \brief C++ API: Interface for writing bytes, and implementation classes. 1.39 + */ 1.40 + 1.41 +#include "unicode/utypes.h" 1.42 +#include "unicode/uobject.h" 1.43 +#include "unicode/std_string.h" 1.44 + 1.45 +U_NAMESPACE_BEGIN 1.46 + 1.47 +/** 1.48 + * A ByteSink can be filled with bytes. 1.49 + * @stable ICU 4.2 1.50 + */ 1.51 +class U_COMMON_API ByteSink : public UMemory { 1.52 +public: 1.53 + /** 1.54 + * Default constructor. 1.55 + * @stable ICU 4.2 1.56 + */ 1.57 + ByteSink() { } 1.58 + /** 1.59 + * Virtual destructor. 1.60 + * @stable ICU 4.2 1.61 + */ 1.62 + virtual ~ByteSink(); 1.63 + 1.64 + /** 1.65 + * Append "bytes[0,n-1]" to this. 1.66 + * @param bytes the pointer to the bytes 1.67 + * @param n the number of bytes; must be non-negative 1.68 + * @stable ICU 4.2 1.69 + */ 1.70 + virtual void Append(const char* bytes, int32_t n) = 0; 1.71 + 1.72 + /** 1.73 + * Returns a writable buffer for appending and writes the buffer's capacity to 1.74 + * *result_capacity. Guarantees *result_capacity>=min_capacity. 1.75 + * May return a pointer to the caller-owned scratch buffer which must have 1.76 + * scratch_capacity>=min_capacity. 1.77 + * The returned buffer is only valid until the next operation 1.78 + * on this ByteSink. 1.79 + * 1.80 + * After writing at most *result_capacity bytes, call Append() with the 1.81 + * pointer returned from this function and the number of bytes written. 1.82 + * Many Append() implementations will avoid copying bytes if this function 1.83 + * returned an internal buffer. 1.84 + * 1.85 + * Partial usage example: 1.86 + * int32_t capacity; 1.87 + * char* buffer = sink->GetAppendBuffer(..., &capacity); 1.88 + * ... Write n bytes into buffer, with n <= capacity. 1.89 + * sink->Append(buffer, n); 1.90 + * In many implementations, that call to Append will avoid copying bytes. 1.91 + * 1.92 + * If the ByteSink allocates or reallocates an internal buffer, it should use 1.93 + * the desired_capacity_hint if appropriate. 1.94 + * If a caller cannot provide a reasonable guess at the desired capacity, 1.95 + * it should pass desired_capacity_hint=0. 1.96 + * 1.97 + * If a non-scratch buffer is returned, the caller may only pass 1.98 + * a prefix to it to Append(). 1.99 + * That is, it is not correct to pass an interior pointer to Append(). 1.100 + * 1.101 + * The default implementation always returns the scratch buffer. 1.102 + * 1.103 + * @param min_capacity required minimum capacity of the returned buffer; 1.104 + * must be non-negative 1.105 + * @param desired_capacity_hint desired capacity of the returned buffer; 1.106 + * must be non-negative 1.107 + * @param scratch default caller-owned buffer 1.108 + * @param scratch_capacity capacity of the scratch buffer 1.109 + * @param result_capacity pointer to an integer which will be set to the 1.110 + * capacity of the returned buffer 1.111 + * @return a buffer with *result_capacity>=min_capacity 1.112 + * @stable ICU 4.2 1.113 + */ 1.114 + virtual char* GetAppendBuffer(int32_t min_capacity, 1.115 + int32_t desired_capacity_hint, 1.116 + char* scratch, int32_t scratch_capacity, 1.117 + int32_t* result_capacity); 1.118 + 1.119 + /** 1.120 + * Flush internal buffers. 1.121 + * Some byte sinks use internal buffers or provide buffering 1.122 + * and require calling Flush() at the end of the stream. 1.123 + * The ByteSink should be ready for further Append() calls after Flush(). 1.124 + * The default implementation of Flush() does nothing. 1.125 + * @stable ICU 4.2 1.126 + */ 1.127 + virtual void Flush(); 1.128 + 1.129 +private: 1.130 + ByteSink(const ByteSink &); // copy constructor not implemented 1.131 + ByteSink &operator=(const ByteSink &); // assignment operator not implemented 1.132 +}; 1.133 + 1.134 +// ------------------------------------------------------------- 1.135 +// Some standard implementations 1.136 + 1.137 +/** 1.138 + * Implementation of ByteSink that writes to a flat byte array, 1.139 + * with bounds-checking: 1.140 + * This sink will not write more than capacity bytes to outbuf. 1.141 + * If more than capacity bytes are Append()ed, then excess bytes are ignored, 1.142 + * and Overflowed() will return true. 1.143 + * Overflow does not cause a runtime error. 1.144 + * @stable ICU 4.2 1.145 + */ 1.146 +class U_COMMON_API CheckedArrayByteSink : public ByteSink { 1.147 +public: 1.148 + /** 1.149 + * Constructs a ByteSink that will write to outbuf[0..capacity-1]. 1.150 + * @param outbuf buffer to write to 1.151 + * @param capacity size of the buffer 1.152 + * @stable ICU 4.2 1.153 + */ 1.154 + CheckedArrayByteSink(char* outbuf, int32_t capacity); 1.155 + /** 1.156 + * Destructor. 1.157 + * @stable ICU 4.2 1.158 + */ 1.159 + virtual ~CheckedArrayByteSink(); 1.160 + /** 1.161 + * Returns the sink to its original state, without modifying the buffer. 1.162 + * Useful for reusing both the buffer and the sink for multiple streams. 1.163 + * Resets the state to NumberOfBytesWritten()=NumberOfBytesAppended()=0 1.164 + * and Overflowed()=FALSE. 1.165 + * @return *this 1.166 + * @stable ICU 4.6 1.167 + */ 1.168 + virtual CheckedArrayByteSink& Reset(); 1.169 + /** 1.170 + * Append "bytes[0,n-1]" to this. 1.171 + * @param bytes the pointer to the bytes 1.172 + * @param n the number of bytes; must be non-negative 1.173 + * @stable ICU 4.2 1.174 + */ 1.175 + virtual void Append(const char* bytes, int32_t n); 1.176 + /** 1.177 + * Returns a writable buffer for appending and writes the buffer's capacity to 1.178 + * *result_capacity. For details see the base class documentation. 1.179 + * @param min_capacity required minimum capacity of the returned buffer; 1.180 + * must be non-negative 1.181 + * @param desired_capacity_hint desired capacity of the returned buffer; 1.182 + * must be non-negative 1.183 + * @param scratch default caller-owned buffer 1.184 + * @param scratch_capacity capacity of the scratch buffer 1.185 + * @param result_capacity pointer to an integer which will be set to the 1.186 + * capacity of the returned buffer 1.187 + * @return a buffer with *result_capacity>=min_capacity 1.188 + * @stable ICU 4.2 1.189 + */ 1.190 + virtual char* GetAppendBuffer(int32_t min_capacity, 1.191 + int32_t desired_capacity_hint, 1.192 + char* scratch, int32_t scratch_capacity, 1.193 + int32_t* result_capacity); 1.194 + /** 1.195 + * Returns the number of bytes actually written to the sink. 1.196 + * @return number of bytes written to the buffer 1.197 + * @stable ICU 4.2 1.198 + */ 1.199 + int32_t NumberOfBytesWritten() const { return size_; } 1.200 + /** 1.201 + * Returns true if any bytes were discarded, i.e., if there was an 1.202 + * attempt to write more than 'capacity' bytes. 1.203 + * @return TRUE if more than 'capacity' bytes were Append()ed 1.204 + * @stable ICU 4.2 1.205 + */ 1.206 + UBool Overflowed() const { return overflowed_; } 1.207 + /** 1.208 + * Returns the number of bytes appended to the sink. 1.209 + * If Overflowed() then NumberOfBytesAppended()>NumberOfBytesWritten() 1.210 + * else they return the same number. 1.211 + * @return number of bytes written to the buffer 1.212 + * @stable ICU 4.6 1.213 + */ 1.214 + int32_t NumberOfBytesAppended() const { return appended_; } 1.215 +private: 1.216 + char* outbuf_; 1.217 + const int32_t capacity_; 1.218 + int32_t size_; 1.219 + int32_t appended_; 1.220 + UBool overflowed_; 1.221 + CheckedArrayByteSink(); ///< default constructor not implemented 1.222 + CheckedArrayByteSink(const CheckedArrayByteSink &); ///< copy constructor not implemented 1.223 + CheckedArrayByteSink &operator=(const CheckedArrayByteSink &); ///< assignment operator not implemented 1.224 +}; 1.225 + 1.226 +#if U_HAVE_STD_STRING 1.227 + 1.228 +/** 1.229 + * Implementation of ByteSink that writes to a "string". 1.230 + * The StringClass is usually instantiated with a std::string. 1.231 + * @stable ICU 4.2 1.232 + */ 1.233 +template<typename StringClass> 1.234 +class StringByteSink : public ByteSink { 1.235 + public: 1.236 + /** 1.237 + * Constructs a ByteSink that will append bytes to the dest string. 1.238 + * @param dest pointer to string object to append to 1.239 + * @stable ICU 4.2 1.240 + */ 1.241 + StringByteSink(StringClass* dest) : dest_(dest) { } 1.242 + /** 1.243 + * Append "bytes[0,n-1]" to this. 1.244 + * @param data the pointer to the bytes 1.245 + * @param n the number of bytes; must be non-negative 1.246 + * @stable ICU 4.2 1.247 + */ 1.248 + virtual void Append(const char* data, int32_t n) { dest_->append(data, n); } 1.249 + private: 1.250 + StringClass* dest_; 1.251 + StringByteSink(); ///< default constructor not implemented 1.252 + StringByteSink(const StringByteSink &); ///< copy constructor not implemented 1.253 + StringByteSink &operator=(const StringByteSink &); ///< assignment operator not implemented 1.254 +}; 1.255 + 1.256 +#endif 1.257 + 1.258 +U_NAMESPACE_END 1.259 + 1.260 +#endif // __BYTESTREAM_H__