mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 10:15:41 +00:00
Bug 770215 - [OS.File] Utilities for strings - Native code. r=froydnj
This commit is contained in:
parent
7417a56a21
commit
53d7d9861a
194
toolkit/components/osfile/osfileutils.cpp
Normal file
194
toolkit/components/osfile/osfileutils.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
|
||||
#include "mozilla/Scoped.h"
|
||||
|
||||
#include "osfileutils.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRTGlue.h"
|
||||
|
||||
// Utilities for handling errors
|
||||
namespace {
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <Windows.h>
|
||||
|
||||
/**
|
||||
* Set the OS-specific error to inform the OS that
|
||||
* the last operation failed because it is not supported.
|
||||
*/
|
||||
void error_not_supported() {
|
||||
SetLastError(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the OS-specific error to inform the OS that
|
||||
* the last operation failed because of an invalid
|
||||
* argument.
|
||||
*/
|
||||
void error_invalid_argument() {
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the OS-specific error to inform the OS that
|
||||
* the last operation failed because of insufficient
|
||||
* memory.
|
||||
*/
|
||||
void error_no_memory() {
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "errno.h"
|
||||
|
||||
/**
|
||||
* Set the OS-specific error to inform the OS that
|
||||
* the last operation failed because it is not supported.
|
||||
*/
|
||||
void error_not_supported() {
|
||||
errno = ENOTSUP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the OS-specific error to inform the OS that
|
||||
* the last operation failed because of an invalid
|
||||
* argument.
|
||||
*/
|
||||
void error_invalid_argument() {
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the OS-specific error to inform the OS that
|
||||
* the last operation failed because of insufficient
|
||||
* memory.
|
||||
*/
|
||||
void error_no_memory() {
|
||||
errno = ENOMEM;
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Memory utilities
|
||||
|
||||
MOZ_EXPORT_API(void) osfile_ns_free(void* buf) {
|
||||
NS_Free(buf);
|
||||
}
|
||||
|
||||
// Unicode utilities
|
||||
|
||||
MOZ_EXPORT_API(PRUnichar*) osfile_wstrdup(PRUnichar* string) {
|
||||
return NS_strdup(string);
|
||||
}
|
||||
|
||||
MOZ_EXPORT_API(PRUnichar*) osfile_DecodeAll(
|
||||
const char* aEncoding,
|
||||
const char* aSource,
|
||||
const int32_t aBytesToDecode)
|
||||
{
|
||||
if (!aEncoding || !aSource) {
|
||||
error_invalid_argument();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICharsetConverterManager> manager =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
error_not_supported();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUnicodeDecoder> decoder;
|
||||
rv = manager->GetUnicodeDecoder(aEncoding, getter_AddRefs(decoder));
|
||||
if (NS_FAILED(rv)) {
|
||||
error_invalid_argument();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Compute an upper bound to the number of chars, allocate buffer
|
||||
|
||||
int32_t srcBytes = aBytesToDecode;
|
||||
int32_t upperBoundChars = 0;
|
||||
rv = decoder->GetMaxLength(aSource, srcBytes, &upperBoundChars);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
int32_t bufSize = (upperBoundChars + 1) * sizeof (PRUnichar);
|
||||
|
||||
mozilla::ScopedFreePtr<PRUnichar> dest((PRUnichar*)NS_Alloc(bufSize));
|
||||
if (dest.get() == nsnull) {
|
||||
error_no_memory();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Convert, add trailing \0
|
||||
|
||||
rv = decoder->Convert(aSource, &srcBytes, dest.rwget(), &upperBoundChars);
|
||||
if (NS_FAILED(rv)) {
|
||||
error_invalid_argument();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
dest.rwget()[upperBoundChars] = '\0';
|
||||
|
||||
return dest.forget();
|
||||
}
|
||||
|
||||
MOZ_EXPORT_API(char*) osfile_EncodeAll(
|
||||
const char* aEncoding,
|
||||
const PRUnichar* aSource,
|
||||
int32_t* aBytesProduced)
|
||||
{
|
||||
if (!aEncoding || !aSource || !aBytesProduced) {
|
||||
error_invalid_argument();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICharsetConverterManager> manager =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
error_not_supported();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUnicodeEncoder> encoder;
|
||||
rv = manager->GetUnicodeEncoder(aEncoding, getter_AddRefs(encoder));
|
||||
if (NS_FAILED(rv)) {
|
||||
error_invalid_argument();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
int32_t srcChars = NS_strlen(aSource);
|
||||
|
||||
int32_t upperBoundBytes = 0;
|
||||
rv = encoder->GetMaxLength(aSource, srcChars, &upperBoundBytes);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
printf_stderr("Encoding %d chars into at up to %d bytes\n", srcChars, upperBoundBytes);
|
||||
int32_t bufSize = upperBoundBytes;
|
||||
mozilla::ScopedFreePtr<char> dest((char*)NS_Alloc(bufSize));
|
||||
|
||||
if (dest.get() == nsnull) {
|
||||
error_no_memory();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
rv = encoder->Convert(aSource, &srcChars, dest.rwget(), &upperBoundBytes);
|
||||
if (NS_FAILED(rv)) {
|
||||
error_invalid_argument();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
*aBytesProduced = upperBoundBytes;
|
||||
return dest.forget();
|
||||
}
|
||||
|
||||
} // extern "C"
|
65
toolkit/components/osfile/osfileutils.h
Normal file
65
toolkit/components/osfile/osfileutils.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef mozilla_osfileutils_h__
|
||||
#define mozilla_osfileutils_h__
|
||||
|
||||
#include "mozilla/Types.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsIUnicodeEncoder.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Memory utilities
|
||||
|
||||
/**
|
||||
* As |NS_Free|, but exported.
|
||||
*/
|
||||
MOZ_EXPORT_API(void) osfile_ns_free(void* buf);
|
||||
|
||||
// Unicode utilities
|
||||
|
||||
/**
|
||||
* Duplicate a Unicode string, as per wpcpy/StrDupW.
|
||||
*
|
||||
* @param source A well-formed, nul-terminated, Unicode string.
|
||||
*
|
||||
* @return Either |NULL| if there was not enough memory to copy the
|
||||
* string, or a new string with the same contents as |source|.
|
||||
* Memory MUST be released with |osfile_ns_free|.
|
||||
*/
|
||||
MOZ_EXPORT_API(PRUnichar*) osfile_wstrdup(PRUnichar* source);
|
||||
|
||||
/**
|
||||
* Decode a nul-terminated C string into a Unicode string.
|
||||
*
|
||||
* @param aEncoding The encoding to use.
|
||||
* @param aSource The C string to decode.
|
||||
* @param aBytesToDecode The number of bytes to decode from |aSource|.
|
||||
*
|
||||
* @return null in case of error, otherwise a sequence of Unicode
|
||||
* chars, representing |aSource|. This memory MUST be released with
|
||||
* |NS_Free|/|osfile_ns_free|.
|
||||
*/
|
||||
MOZ_EXPORT_API(PRUnichar*) osfile_DecodeAll(
|
||||
const char* aEncoding,
|
||||
const char* aSource,
|
||||
const int32_t aBytesToDecode);
|
||||
|
||||
/**
|
||||
* Encode a complete Unicode string into a set of bytes.
|
||||
*
|
||||
* @param aEncoding The encoding to use.
|
||||
* @param aSource The Unicode string to encode. Must be nul-terminated.
|
||||
* @param aBytesWritten (out) The number of bytes encoded.
|
||||
*
|
||||
* @return null in case of error, otherwise a new buffer. The
|
||||
* number of bytes actually allocated may be higher than
|
||||
* |aBytesWritten|. The buffer MUST be released with
|
||||
* |NS_Free|/|osfile_ns_free|.
|
||||
*/
|
||||
MOZ_EXPORT_API(char*) osfile_EncodeAll(
|
||||
const char* aEncoding,
|
||||
const PRUnichar* aSource,
|
||||
int32_t* aBytesWritten);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // mozilla_osfileutils_h__
|
Loading…
Reference in New Issue
Block a user