* The recent files list now also preserves the case of the MIME strings.
* STL allocations are guarded by a try/catch block. * As in RecentApps, Get() did not properly populate an error condition. * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19263 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -82,7 +82,7 @@ RecentApps::Add(const char *appSig, int32 appFlags)
|
|||||||
// of recent apps
|
// of recent apps
|
||||||
if (!strcasecmp(appSig, kTrackerSignature)
|
if (!strcasecmp(appSig, kTrackerSignature)
|
||||||
|| !strcasecmp(appSig, kDeskbarSignature)
|
|| !strcasecmp(appSig, kDeskbarSignature)
|
||||||
|| (appFlags & B_ARGV_ONLY) != 0 || (appFlags & B_BACKGROUND_APP) != 0)
|
|| (appFlags & (B_ARGV_ONLY | B_BACKGROUND_APP)) != 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// Remove any previous instance
|
// Remove any previous instance
|
||||||
|
|||||||
@@ -1,31 +1,14 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2001-2005, Haiku
|
* Copyright 2001-2006, Haiku Inc.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Tyler Dauwalder
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
* Ingo Weinhold, [email protected]
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
* Axel Dörfler, [email protected]e
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
*/
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
//! Recently launched apps list
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// File Name: RecentEntries.cpp
|
|
||||||
// Author: Tyler Dauwalder ([email protected])
|
|
||||||
// Description: Recently launched apps list
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/*! \file RecentEntries.cpp
|
|
||||||
\brief RecentEntries class implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "RecentEntries.h"
|
#include "RecentEntries.h"
|
||||||
|
|
||||||
@@ -48,9 +31,6 @@ using namespace std;
|
|||||||
//#define DBG(x)
|
//#define DBG(x)
|
||||||
#define OUT printf
|
#define OUT printf
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// recent_entry
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*! \struct recent_entry
|
/*! \struct recent_entry
|
||||||
|
|
||||||
@@ -64,16 +44,17 @@ using namespace std;
|
|||||||
/*! \brief Creates a new recent_entry object.
|
/*! \brief Creates a new recent_entry object.
|
||||||
*/
|
*/
|
||||||
recent_entry::recent_entry(const entry_ref *ref, const char *appSig,
|
recent_entry::recent_entry(const entry_ref *ref, const char *appSig,
|
||||||
uint32 index)
|
uint32 index)
|
||||||
: ref(ref ? *ref : entry_ref())
|
:
|
||||||
, sig(appSig)
|
ref(ref ? *ref : entry_ref()),
|
||||||
, index(index)
|
sig(appSig),
|
||||||
|
index(index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// RecentEntries
|
// #pragma mark -
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*! \class RecentEntries
|
/*! \class RecentEntries
|
||||||
\brief Implements the common functionality used by the roster's recent
|
\brief Implements the common functionality used by the roster's recent
|
||||||
@@ -88,7 +69,7 @@ recent_entry::recent_entry(const entry_ref *ref, const char *appSig,
|
|||||||
signatures are case-independent.
|
signatures are case-independent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a new list.
|
/*! \brief Creates a new list.
|
||||||
|
|
||||||
The list is initially empty.
|
The list is initially empty.
|
||||||
@@ -97,7 +78,7 @@ RecentEntries::RecentEntries()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with the object.
|
/*! \brief Frees all resources associated with the object.
|
||||||
*/
|
*/
|
||||||
RecentEntries::~RecentEntries()
|
RecentEntries::~RecentEntries()
|
||||||
@@ -105,7 +86,7 @@ RecentEntries::~RecentEntries()
|
|||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add
|
|
||||||
/*! \brief Places the given entry Places the app with the given signature at the front of
|
/*! \brief Places the given entry Places the app with the given signature at the front of
|
||||||
the recent apps list.
|
the recent apps list.
|
||||||
|
|
||||||
@@ -124,31 +105,33 @@ RecentEntries::~RecentEntries()
|
|||||||
status_t
|
status_t
|
||||||
RecentEntries::Add(const entry_ref *ref, const char *appSig)
|
RecentEntries::Add(const entry_ref *ref, const char *appSig)
|
||||||
{
|
{
|
||||||
std::string sig;
|
if (ref == NULL || appSig == NULL)
|
||||||
status_t error = ref && appSig ? B_OK : B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
if (!error) {
|
|
||||||
// Store all sigs as lowercase
|
// Look for a previous instance of this entry
|
||||||
sig = BPrivate::Storage::to_lower(appSig);
|
std::list<recent_entry*>::iterator item;
|
||||||
|
for (item = fEntryList.begin(); item != fEntryList.end(); item++) {
|
||||||
// Look for a previous instance of this entry
|
if ((*item)->ref == *ref && !strcasecmp((*item)->sig.c_str(), appSig)) {
|
||||||
std::list<recent_entry*>::iterator item;
|
fEntryList.erase(item);
|
||||||
for (item = fEntryList.begin(); item != fEntryList.end(); item++) {
|
break;
|
||||||
if ((*item)->ref == *ref && (*item)->sig == sig) {
|
|
||||||
fEntryList.erase(item);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add this entry to the front of the list
|
|
||||||
recent_entry *entry = new(nothrow) recent_entry(ref, appSig, 0);
|
|
||||||
error = entry ? B_OK : B_NO_MEMORY;
|
|
||||||
if (!error)
|
|
||||||
fEntryList.push_front(entry);
|
|
||||||
}
|
}
|
||||||
return error;
|
|
||||||
|
// Add this entry to the front of the list
|
||||||
|
recent_entry *entry = new (nothrow) recent_entry(ref, appSig, 0);
|
||||||
|
if (entry == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fEntryList.push_front(entry);
|
||||||
|
} catch (...) {
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get
|
|
||||||
/*! \brief Returns the first \a maxCount recent apps in the \c BMessage
|
/*! \brief Returns the first \a maxCount recent apps in the \c BMessage
|
||||||
pointed to by \a list.
|
pointed to by \a list.
|
||||||
|
|
||||||
@@ -171,82 +154,87 @@ RecentEntries::Add(const entry_ref *ref, const char *appSig)
|
|||||||
expected to be all lowercase.
|
expected to be all lowercase.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
RecentEntries::Get(int32 maxCount, const char *fileTypes[], int32 fileTypesCount,
|
RecentEntries::Get(int32 maxCount, const char *fileTypes[],
|
||||||
const char *appSig, BMessage *result)
|
int32 fileTypesCount, const char *appSig, BMessage *result)
|
||||||
{
|
{
|
||||||
status_t error = result && (fileTypesCount == 0 || (fileTypesCount > 0 && fileTypes))
|
if (result == NULL
|
||||||
? B_OK : B_BAD_VALUE;
|
|| fileTypesCount < 0
|
||||||
if (!error) {
|
|| (fileTypesCount > 0 && fileTypes == NULL))
|
||||||
result->MakeEmpty();
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
std::list<recent_entry*> duplicateList;
|
result->MakeEmpty();
|
||||||
std::list<recent_entry*>::iterator item;
|
|
||||||
int count = 0;
|
std::list<recent_entry*> duplicateList;
|
||||||
|
std::list<recent_entry*>::iterator item;
|
||||||
for (item = fEntryList.begin();
|
status_t error = B_OK;
|
||||||
count < maxCount && item != fEntryList.end();
|
int count = 0;
|
||||||
item++)
|
|
||||||
{
|
for (item = fEntryList.begin();
|
||||||
bool match = true;
|
error == B_OK && count < maxCount && item != fEntryList.end();
|
||||||
// Filter if necessary
|
item++) {
|
||||||
if (fileTypesCount > 0 || appSig) {
|
// Filter by app sig
|
||||||
match = false;
|
if (appSig != NULL && strcasecmp((*item)->sig.c_str(), appSig))
|
||||||
// Filter by app sig
|
continue;
|
||||||
if (appSig)
|
|
||||||
match = (*item)->sig == appSig;
|
// Filter by file type
|
||||||
// Filter by file type
|
if (fileTypesCount > 0) {
|
||||||
if (!match && fileTypesCount > 0) {
|
char type[B_MIME_TYPE_LENGTH];
|
||||||
char type[B_MIME_TYPE_LENGTH];
|
if (GetTypeForRef(&(*item)->ref, type) == B_OK) {
|
||||||
if (GetTypeForRef(&(*item)->ref, type) == B_OK) {
|
bool match = false;
|
||||||
for (int i = 0; i < fileTypesCount; i++) {
|
for (int i = 0; i < fileTypesCount; i++) {
|
||||||
if (strcasecmp(type, fileTypes[i]) == 0) {
|
if (!strcasecmp(type, fileTypes[i])) {
|
||||||
match = true;
|
match = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match) {
|
|
||||||
// Check for duplicates
|
|
||||||
for (std::list<recent_entry*>::iterator dupItem
|
|
||||||
= duplicateList.begin();
|
|
||||||
dupItem != duplicateList.end();
|
|
||||||
dupItem++)
|
|
||||||
{
|
|
||||||
if ((*dupItem)->ref == (*item)->ref) {
|
|
||||||
match = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!match)
|
||||||
if (match) {
|
continue;
|
||||||
// Add the ref to the list used to check
|
|
||||||
// for duplicates, and then to the result
|
|
||||||
duplicateList.push_back(*item);
|
|
||||||
result->AddRef("refs", &(*item)->ref);
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for duplicates
|
||||||
|
bool duplicate = false;
|
||||||
|
for (std::list<recent_entry*>::iterator dupItem = duplicateList.begin();
|
||||||
|
dupItem != duplicateList.end(); dupItem++) {
|
||||||
|
if ((*dupItem)->ref == (*item)->ref) {
|
||||||
|
duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (duplicate)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Add the ref to the list used to check
|
||||||
|
// for duplicates, and then to the result
|
||||||
|
try {
|
||||||
|
duplicateList.push_back(*item);
|
||||||
|
} catch (...) {
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
if (error == B_OK)
|
||||||
|
error = result->AddRef("refs", &(*item)->ref);
|
||||||
|
if (error == B_OK)
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear
|
|
||||||
/*! \brief Clears the list of recently launched apps
|
/*! \brief Clears the list of recently launched apps
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
RecentEntries::Clear()
|
RecentEntries::Clear()
|
||||||
{
|
{
|
||||||
std::list<recent_entry*>::iterator i;
|
std::list<recent_entry*>::iterator i;
|
||||||
for (i = fEntryList.begin(); i != fEntryList.end(); i++)
|
for (i = fEntryList.begin(); i != fEntryList.end(); i++) {
|
||||||
delete *i;
|
delete *i;
|
||||||
|
}
|
||||||
fEntryList.clear();
|
fEntryList.clear();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print
|
|
||||||
/*! \brief Dumps the the current list of entries to stdout.
|
/*! \brief Dumps the the current list of entries to stdout.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
@@ -254,10 +242,7 @@ RecentEntries::Print()
|
|||||||
{
|
{
|
||||||
std::list<recent_entry*>::iterator item;
|
std::list<recent_entry*>::iterator item;
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
for (item = fEntryList.begin();
|
for (item = fEntryList.begin(); item != fEntryList.end(); item++) {
|
||||||
item != fEntryList.end();
|
|
||||||
item++)
|
|
||||||
{
|
|
||||||
printf("%d: device == '%ld', dir == '%lld', name == '%s', app == '%s', index == %ld\n",
|
printf("%d: device == '%ld', dir == '%lld', name == '%s', app == '%s', index == %ld\n",
|
||||||
counter++, (*item)->ref.device, (*item)->ref.directory, (*item)->ref.name,
|
counter++, (*item)->ref.device, (*item)->ref.directory, (*item)->ref.name,
|
||||||
(*item)->sig.c_str(), (*item)->index);
|
(*item)->sig.c_str(), (*item)->index);
|
||||||
@@ -265,31 +250,31 @@ RecentEntries::Print()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save
|
|
||||||
status_t
|
status_t
|
||||||
RecentEntries::Save(FILE* file, const char *description, const char *tag)
|
RecentEntries::Save(FILE* file, const char *description, const char *tag)
|
||||||
{
|
{
|
||||||
status_t error = file ? B_OK : B_BAD_VALUE;
|
if (file == NULL || description == NULL || tag == NULL)
|
||||||
if (!error) {
|
return B_BAD_VALUE;
|
||||||
fprintf(file, "# %s\n", description);
|
|
||||||
|
|
||||||
/* In order to write our entries out in the format used by the
|
fprintf(file, "# %s\n", description);
|
||||||
Roster settings file, we need to collect all the signatures
|
|
||||||
for each entry in one place, while at the same time updating
|
/* In order to write our entries out in the format used by the
|
||||||
the index values for each entry/sig pair to reflect the current
|
Roster settings file, we need to collect all the signatures
|
||||||
ordering of the list. I believe this is the data structure
|
for each entry in one place, while at the same time updating
|
||||||
R5 actually maintains all the time, as their indices do not
|
the index values for each entry/sig pair to reflect the current
|
||||||
change over time (whereas ours will). If our implementation
|
ordering of the list. I believe this is the data structure
|
||||||
proves to be slower that R5, we may want to consider using
|
R5 actually maintains all the time, as their indices do not
|
||||||
the data structure pervasively.
|
change over time (whereas ours will). If our implementation
|
||||||
*/
|
proves to be slower that R5, we may want to consider using
|
||||||
std::map<entry_ref, std::list<recent_entry*> > map;
|
the data structure pervasively.
|
||||||
uint32 count = fEntryList.size();
|
*/
|
||||||
|
std::map<entry_ref, std::list<recent_entry*> > map;
|
||||||
|
uint32 count = fEntryList.size();
|
||||||
|
|
||||||
|
try {
|
||||||
for (std::list<recent_entry*>::iterator item = fEntryList.begin();
|
for (std::list<recent_entry*>::iterator item = fEntryList.begin();
|
||||||
item != fEntryList.end();
|
item != fEntryList.end(); count--, item++) {
|
||||||
count--, item++)
|
|
||||||
{
|
|
||||||
recent_entry *entry = *item;
|
recent_entry *entry = *item;
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry->index = count;
|
entry->index = count;
|
||||||
@@ -300,49 +285,47 @@ RecentEntries::Save(FILE* file, const char *description, const char *tag)
|
|||||||
fEntryList.size() - count));
|
fEntryList.size() - count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (...) {
|
||||||
for (std::map<entry_ref, std::list<recent_entry*> >::iterator mapItem
|
return B_NO_MEMORY;
|
||||||
= map.begin();
|
|
||||||
mapItem != map.end();
|
|
||||||
mapItem++)
|
|
||||||
{
|
|
||||||
// We're going to need to properly escape the path name we
|
|
||||||
// get, which will at absolute worst double the length of
|
|
||||||
// the string.
|
|
||||||
BPath path;
|
|
||||||
char escapedPath[B_PATH_NAME_LENGTH*2];
|
|
||||||
status_t outputError = path.SetTo(&mapItem->first);
|
|
||||||
if (!outputError) {
|
|
||||||
BPrivate::Storage::escape_path(path.Path(), escapedPath);
|
|
||||||
fprintf(file, "%s %s", tag, escapedPath);
|
|
||||||
std::list<recent_entry*> &list = mapItem->second;
|
|
||||||
int32 i = 0;
|
|
||||||
for (std::list<recent_entry*>::iterator item = list.begin();
|
|
||||||
item != list.end();
|
|
||||||
i++, item++)
|
|
||||||
{
|
|
||||||
recent_entry *entry = *item;
|
|
||||||
if (entry)
|
|
||||||
fprintf(file, " \"%s\" %ld", entry->sig.c_str(), entry->index);
|
|
||||||
else {
|
|
||||||
DBG(OUT("WARNING: RecentEntries::Save(): The entry %ld entries "
|
|
||||||
"from the front of the compiled recent_entry* list for the "
|
|
||||||
"entry ref (%ld, %lld, '%s') was found to be NULL\n",
|
|
||||||
i, mapItem->first.device, mapItem->first.directory,
|
|
||||||
mapItem->first.name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(file, "\n");
|
|
||||||
} else {
|
|
||||||
DBG(OUT("WARNING: RecentEntries::Save(): entry_ref_to_path() failed on "
|
|
||||||
"the entry_ref (%ld, %lld, '%s') with error 0x%lx\n",
|
|
||||||
mapItem->first.device, mapItem->first.directory,
|
|
||||||
mapItem->first.name, outputError));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(file, "\n");
|
|
||||||
}
|
}
|
||||||
return error;
|
|
||||||
|
for (std::map<entry_ref, std::list<recent_entry*> >::iterator mapItem = map.begin();
|
||||||
|
mapItem != map.end(); mapItem++) {
|
||||||
|
// We're going to need to properly escape the path name we
|
||||||
|
// get, which will at absolute worst double the length of
|
||||||
|
// the string.
|
||||||
|
BPath path;
|
||||||
|
char escapedPath[B_PATH_NAME_LENGTH*2];
|
||||||
|
status_t outputError = path.SetTo(&mapItem->first);
|
||||||
|
if (!outputError) {
|
||||||
|
BPrivate::Storage::escape_path(path.Path(), escapedPath);
|
||||||
|
fprintf(file, "%s %s", tag, escapedPath);
|
||||||
|
std::list<recent_entry*> &list = mapItem->second;
|
||||||
|
int32 i = 0;
|
||||||
|
for (std::list<recent_entry*>::iterator item = list.begin();
|
||||||
|
item != list.end(); i++, item++) {
|
||||||
|
recent_entry *entry = *item;
|
||||||
|
if (entry)
|
||||||
|
fprintf(file, " \"%s\" %ld", entry->sig.c_str(), entry->index);
|
||||||
|
else {
|
||||||
|
DBG(OUT("WARNING: RecentEntries::Save(): The entry %ld entries "
|
||||||
|
"from the front of the compiled recent_entry* list for the "
|
||||||
|
"entry ref (%ld, %lld, '%s') was found to be NULL\n",
|
||||||
|
i, mapItem->first.device, mapItem->first.directory,
|
||||||
|
mapItem->first.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(file, "\n");
|
||||||
|
} else {
|
||||||
|
DBG(OUT("WARNING: RecentEntries::Save(): entry_ref_to_path() failed on "
|
||||||
|
"the entry_ref (%ld, %lld, '%s') with error 0x%lx\n",
|
||||||
|
mapItem->first.device, mapItem->first.directory,
|
||||||
|
mapItem->first.name, outputError));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "\n");
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -355,20 +338,20 @@ RecentEntries::Save(FILE* file, const char *description, const char *tag)
|
|||||||
status_t
|
status_t
|
||||||
RecentEntries::GetTypeForRef(const entry_ref *ref, char *result)
|
RecentEntries::GetTypeForRef(const entry_ref *ref, char *result)
|
||||||
{
|
{
|
||||||
|
if (ref == NULL || result == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// Read the type
|
||||||
BNode node;
|
BNode node;
|
||||||
status_t error = ref && result ? B_OK : B_BAD_VALUE;
|
status_t error = node.SetTo(ref);
|
||||||
// Read the type and force to lowercase
|
if (error == B_OK) {
|
||||||
if (!error)
|
|
||||||
error = node.SetTo(ref);
|
|
||||||
if (!error) {
|
|
||||||
ssize_t bytes = node.ReadAttr("BEOS:TYPE", B_MIME_STRING_TYPE,
|
ssize_t bytes = node.ReadAttr("BEOS:TYPE", B_MIME_STRING_TYPE,
|
||||||
0, result, B_MIME_TYPE_LENGTH-1);
|
0, result, B_MIME_TYPE_LENGTH - 1);
|
||||||
if (bytes < 0)
|
if (bytes < B_OK)
|
||||||
error = bytes;
|
error = bytes;
|
||||||
else
|
else
|
||||||
result[bytes] = '\0';
|
result[bytes] = '\0';
|
||||||
}
|
}
|
||||||
if (!error)
|
|
||||||
BPrivate::Storage::to_lower(result);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user